|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_000 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_001 | |||
|---|---|---|---|---|
|
126 lines 5326 bytes Last modified : Mon May 14 20:27:08 2012 |
127 lines 5355 bytes Last modified : Mon May 14 20:27:08 2012 |
|||
| 1 | //Time : 2012-04-12 06:34:46.721 | 1 | //Time : 2012-04-12 06:35:05.964 | |
| 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.EnumMap; | 4 | import java.util.EnumMap; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Map; | 7 | import java.util.Map; | |
| 8 | import java.util.Map.Entry; | 8 | import java.util.Map.Entry; | |
| 9 | import java.util.Set; | 9 | import java.util.Set; | |
| 10 | import com.ibm.wala.types.FieldReference; | 10 | import com.ibm.wala.types.FieldReference; | |
| 11 | import com.ibm.wala.util.collections.Pair; | 11 | import com.ibm.wala.util.collections.Pair; | |
| 12 | import energy.components.Component; | 12 | import energy.components.Component; | |
| 13 | import energy.interproc.CompoundLockState; | 13 | import energy.interproc.CompoundLockState; | |
| 14 | import energy.interproc.SingleLockState; | 14 | import energy.interproc.SingleLockState; | |
| 15 | import energy.util.E; | 15 | import energy.util.E; | |
| 16 | public class AnalysisResults { | 16 | public class AnalysisResults { | |
| 17 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | 17 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | |
| 18 | public class ComponentResult { | 18 | public class ComponentResult { | |
| 19 | HashMap<String,CompoundLockState> callBackExitStates; | 19 | HashMap<String,CompoundLockState> callBackExitStates; | |
| 20 | public ComponentResult(){ | 20 | public ComponentResult(){ | |
| 21 | callBackExitStates=new HashMap<String,CompoundLockState>(); | 21 | callBackExitStates=new HashMap<String,CompoundLockState>(); | |
| 22 | } | 22 | } | |
| 23 | } | 23 | } | |
| 24 | /** | 24 | /** | |
| 25 | * The constructor | 25 | * The constructor | |
| 26 | */ | 26 | */ | |
| 27 | AnalysisResults(){ | 27 | AnalysisResults(){ | |
| 28 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | 28 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | |
| 29 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | 29 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | |
| 30 | } | 30 | } | |
| 31 | int threadCount=0; | 31 | int threadCount=0; | |
| 32 | int activityCount=0; | 32 | int activityCount=0; | |
| 33 | int lockThreads=0; | 33 | int lockThreads=0; | |
| 34 | int nolockThreads=0; | 34 | int nolockThreads=0; | |
| 35 | int unlockThreads=0; | 35 | int unlockThreads=0; | |
| 36 | int lockunlockThreads=0; | 36 | int lockunlockThreads=0; | |
| 37 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 37 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 38 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | 38 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | |
| 39 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | 39 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | |
| 40 | resultStuff.add(Pair.make(component,map)); | 40 | resultStuff.add(Pair.make(component,map)); | |
| 41 | StringBuffer sb=new StringBuffer(); | 41 | StringBuffer sb=new StringBuffer(); | |
| 42 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | 42 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | |
| 43 | if (e.getValue().size() > 0) { | 43 | if (e.getValue().size() > 0) { | |
| 44 | sb.append(e.getKey() + "\n"); | 44 | sb.append(e.getKey() + "\n"); | |
| 45 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | 45 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | |
| 46 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | 46 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | |
| 47 | } | 47 | } | |
| 48 | } | 48 | } | |
| 49 | } | 49 | } | |
| 50 | if (sb.length() > 0) { | 50 | if (sb.length() > 0) { | |
| 51 | E.log(1,component.toString() + "\n" + sb.toString()); | 51 | E.log(1,component.toString() + "\n" + sb.toString()); | |
| 52 | } | 52 | } | |
| 53 | } | 53 | } | |
| 54 | private LockUsage getLockUsage( SingleLockState runState){ | 54 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 55 | if (runState != null) { | 55 | if (runState != null) { | |
| 56 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 56 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 57 | return LockUsage.LOCKING; | 57 | return LockUsage.LOCKING; | |
| 58 | } | 58 | } | |
| 59 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 59 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 60 | return LockUsage.EMPTY; | 60 | return LockUsage.EMPTY; | |
| 61 | } | 61 | } | |
| 62 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 62 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 63 | return LockUsage.FULL_UNLOCKING; | 63 | return LockUsage.FULL_UNLOCKING; | |
| 64 | } | 64 | } | |
| 65 | else if (runState.isMaybeReleased()) { | 65 | else if (runState.isMaybeReleased()) { | |
| 66 | return LockUsage.UNLOCKING; | 66 | return LockUsage.UNLOCKING; | |
| 67 | } | 67 | } | |
| 68 | else { | 68 | else { | |
| 69 | return LockUsage.UNKNOWN_STATE; | 69 | return LockUsage.UNKNOWN_STATE; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | else { | 72 | else { | |
| 73 | return LockUsage.EMPTY; | 73 | return LockUsage.EMPTY; | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | public void processResults(){ | 76 | public void processResults(){ | |
| 77 | System.out.pr=$missing$; | |||
| 77 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | 78 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | |
| 78 | Component component=pair.fst; | 79 | Component component=pair.fst; | |
| 79 | String componentName=component.getComponentName(); | 80 | String componentName=component.getComponentName(); | |
| 80 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | 81 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | |
| 81 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | 82 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | |
| 82 | String callBackName=e.getKey(); | 83 | String callBackName=e.getKey(); | |
| 83 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | 84 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | |
| 84 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | 85 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | |
| 85 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | 86 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | |
| 86 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | 87 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | |
| 87 | FieldReference field=fs.getKey(); | 88 | FieldReference field=fs.getKey(); | |
| 88 | Set<SingleLockState> sls=fs.getValue(); | 89 | Set<SingleLockState> sls=fs.getValue(); | |
| 89 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 90 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 90 | LockUsage lockUsage=getLockUsage(sl); | 91 | LockUsage lockUsage=getLockUsage(sl); | |
| 91 | lockUsages.put(field,lockUsage); | 92 | lockUsages.put(field,lockUsage); | |
| 92 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | 93 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | |
| 93 | if (lockUsage != LockUsage.EMPTY) { | 94 | if (lockUsage != LockUsage.EMPTY) { | |
| 94 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | 95 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | |
| 95 | } | 96 | } | |
| 96 | updateEnumMap(enumMap,lockUsage); | 97 | updateEnumMap(enumMap,lockUsage); | |
| 97 | } | 98 | } | |
| 98 | } | 99 | } | |
| 99 | } | 100 | } | |
| 100 | } | 101 | } | |
| 101 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | 102 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | |
| 102 | if (enumMap == null) { | 103 | if (enumMap == null) { | |
| 103 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | 104 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | |
| 104 | } | 105 | } | |
| 105 | Integer count=enumMap.get(lockUsage); | 106 | Integer count=enumMap.get(lockUsage); | |
| 106 | if (count == null) { | 107 | if (count == null) { | |
| 107 | count=new Integer(1); | 108 | count=new Integer(1); | |
| 108 | enumMap.put(lockUsage,count); | 109 | enumMap.put(lockUsage,count); | |
| 109 | } | 110 | } | |
| 110 | else { | 111 | else { | |
| 111 | enumMap.put(lockUsage,count + 1); | 112 | enumMap.put(lockUsage,count + 1); | |
| 112 | } | 113 | } | |
| 113 | } | 114 | } | |
| 114 | public void outputFinalResults(){ | 115 | public void outputFinalResults(){ | |
| 115 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | 116 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | |
| 116 | Pair<String,String> key=e.getKey(); | 117 | Pair<String,String> key=e.getKey(); | |
| 117 | E.log(1,key.toString()); | 118 | E.log(1,key.toString()); | |
| 118 | EnumMap<LockUsage,Integer> usages=e.getValue(); | 119 | EnumMap<LockUsage,Integer> usages=e.getValue(); | |
| 119 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | 120 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | |
| 120 | LockUsage usage=u.getKey(); | 121 | LockUsage usage=u.getKey(); | |
| 121 | Integer count=u.getValue(); | 122 | Integer count=u.getValue(); | |
| 122 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | 123 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | |
| 123 | } | 124 | } | |
| 124 | } | 125 | } | |
| 125 | } | 126 | } | |
| 126 | } | 127 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_001 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_002 | |||
|---|---|---|---|---|
|
127 lines 5355 bytes Last modified : Mon May 14 20:27:08 2012 |
127 lines 5352 bytes Last modified : Mon May 14 20:27:08 2012 |
|||
| 1 | //Time : 2012-04-12 06:35:05.964 | 1 | //Time : 2012-04-12 06:35:08.289 | |
| 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.EnumMap; | 4 | import java.util.EnumMap; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Map; | 7 | import java.util.Map; | |
| 8 | import java.util.Map.Entry; | 8 | import java.util.Map.Entry; | |
| 9 | import java.util.Set; | 9 | import java.util.Set; | |
| 10 | import com.ibm.wala.types.FieldReference; | 10 | import com.ibm.wala.types.FieldReference; | |
| 11 | import com.ibm.wala.util.collections.Pair; | 11 | import com.ibm.wala.util.collections.Pair; | |
| 12 | import energy.components.Component; | 12 | import energy.components.Component; | |
| 13 | import energy.interproc.CompoundLockState; | 13 | import energy.interproc.CompoundLockState; | |
| 14 | import energy.interproc.SingleLockState; | 14 | import energy.interproc.SingleLockState; | |
| 15 | import energy.util.E; | 15 | import energy.util.E; | |
| 16 | public class AnalysisResults { | 16 | public class AnalysisResults { | |
| 17 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | 17 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | |
| 18 | public class ComponentResult { | 18 | public class ComponentResult { | |
| 19 | HashMap<String,CompoundLockState> callBackExitStates; | 19 | HashMap<String,CompoundLockState> callBackExitStates; | |
| 20 | public ComponentResult(){ | 20 | public ComponentResult(){ | |
| 21 | callBackExitStates=new HashMap<String,CompoundLockState>(); | 21 | callBackExitStates=new HashMap<String,CompoundLockState>(); | |
| 22 | } | 22 | } | |
| 23 | } | 23 | } | |
| 24 | /** | 24 | /** | |
| 25 | * The constructor | 25 | * The constructor | |
| 26 | */ | 26 | */ | |
| 27 | AnalysisResults(){ | 27 | AnalysisResults(){ | |
| 28 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | 28 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | |
| 29 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | 29 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | |
| 30 | } | 30 | } | |
| 31 | int threadCount=0; | 31 | int threadCount=0; | |
| 32 | int activityCount=0; | 32 | int activityCount=0; | |
| 33 | int lockThreads=0; | 33 | int lockThreads=0; | |
| 34 | int nolockThreads=0; | 34 | int nolockThreads=0; | |
| 35 | int unlockThreads=0; | 35 | int unlockThreads=0; | |
| 36 | int lockunlockThreads=0; | 36 | int lockunlockThreads=0; | |
| 37 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 37 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 38 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | 38 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | |
| 39 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | 39 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | |
| 40 | resultStuff.add(Pair.make(component,map)); | 40 | resultStuff.add(Pair.make(component,map)); | |
| 41 | StringBuffer sb=new StringBuffer(); | 41 | StringBuffer sb=new StringBuffer(); | |
| 42 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | 42 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | |
| 43 | if (e.getValue().size() > 0) { | 43 | if (e.getValue().size() > 0) { | |
| 44 | sb.append(e.getKey() + "\n"); | 44 | sb.append(e.getKey() + "\n"); | |
| 45 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | 45 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | |
| 46 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | 46 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | |
| 47 | } | 47 | } | |
| 48 | } | 48 | } | |
| 49 | } | 49 | } | |
| 50 | if (sb.length() > 0) { | 50 | if (sb.length() > 0) { | |
| 51 | E.log(1,component.toString() + "\n" + sb.toString()); | 51 | E.log(1,component.toString() + "\n" + sb.toString()); | |
| 52 | } | 52 | } | |
| 53 | } | 53 | } | |
| 54 | private LockUsage getLockUsage( SingleLockState runState){ | 54 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 55 | if (runState != null) { | 55 | if (runState != null) { | |
| 56 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 56 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 57 | return LockUsage.LOCKING; | 57 | return LockUsage.LOCKING; | |
| 58 | } | 58 | } | |
| 59 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 59 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 60 | return LockUsage.EMPTY; | 60 | return LockUsage.EMPTY; | |
| 61 | } | 61 | } | |
| 62 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 62 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 63 | return LockUsage.FULL_UNLOCKING; | 63 | return LockUsage.FULL_UNLOCKING; | |
| 64 | } | 64 | } | |
| 65 | else if (runState.isMaybeReleased()) { | 65 | else if (runState.isMaybeReleased()) { | |
| 66 | return LockUsage.UNLOCKING; | 66 | return LockUsage.UNLOCKING; | |
| 67 | } | 67 | } | |
| 68 | else { | 68 | else { | |
| 69 | return LockUsage.UNKNOWN_STATE; | 69 | return LockUsage.UNKNOWN_STATE; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | else { | 72 | else { | |
| 73 | return LockUsage.EMPTY; | 73 | return LockUsage.EMPTY; | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | public void processResults(){ | 76 | public void processResults(){ | |
| 77 | System.out.pr=$missing$; | 77 | System.out.println(); | |
| 78 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | 78 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | |
| 79 | Component component=pair.fst; | 79 | Component component=pair.fst; | |
| 80 | String componentName=component.getComponentName(); | 80 | String componentName=component.getComponentName(); | |
| 81 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | 81 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | |
| 82 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | 82 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | |
| 83 | String callBackName=e.getKey(); | 83 | String callBackName=e.getKey(); | |
| 84 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | 84 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | |
| 85 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | 85 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | |
| 86 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | 86 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | |
| 87 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | 87 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | |
| 88 | FieldReference field=fs.getKey(); | 88 | FieldReference field=fs.getKey(); | |
| 89 | Set<SingleLockState> sls=fs.getValue(); | 89 | Set<SingleLockState> sls=fs.getValue(); | |
| 90 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 90 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 91 | LockUsage lockUsage=getLockUsage(sl); | 91 | LockUsage lockUsage=getLockUsage(sl); | |
| 92 | lockUsages.put(field,lockUsage); | 92 | lockUsages.put(field,lockUsage); | |
| 93 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | 93 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | |
| 94 | if (lockUsage != LockUsage.EMPTY) { | 94 | if (lockUsage != LockUsage.EMPTY) { | |
| 95 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | 95 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | |
| 96 | } | 96 | } | |
| 97 | updateEnumMap(enumMap,lockUsage); | 97 | updateEnumMap(enumMap,lockUsage); | |
| 98 | } | 98 | } | |
| 99 | } | 99 | } | |
| 100 | } | 100 | } | |
| 101 | } | 101 | } | |
| 102 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | 102 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | |
| 103 | if (enumMap == null) { | 103 | if (enumMap == null) { | |
| 104 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | 104 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | |
| 105 | } | 105 | } | |
| 106 | Integer count=enumMap.get(lockUsage); | 106 | Integer count=enumMap.get(lockUsage); | |
| 107 | if (count == null) { | 107 | if (count == null) { | |
| 108 | count=new Integer(1); | 108 | count=new Integer(1); | |
| 109 | enumMap.put(lockUsage,count); | 109 | enumMap.put(lockUsage,count); | |
| 110 | } | 110 | } | |
| 111 | else { | 111 | else { | |
| 112 | enumMap.put(lockUsage,count + 1); | 112 | enumMap.put(lockUsage,count + 1); | |
| 113 | } | 113 | } | |
| 114 | } | 114 | } | |
| 115 | public void outputFinalResults(){ | 115 | public void outputFinalResults(){ | |
| 116 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | 116 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | |
| 117 | Pair<String,String> key=e.getKey(); | 117 | Pair<String,String> key=e.getKey(); | |
| 118 | E.log(1,key.toString()); | 118 | E.log(1,key.toString()); | |
| 119 | EnumMap<LockUsage,Integer> usages=e.getValue(); | 119 | EnumMap<LockUsage,Integer> usages=e.getValue(); | |
| 120 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | 120 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | |
| 121 | LockUsage usage=u.getKey(); | 121 | LockUsage usage=u.getKey(); | |
| 122 | Integer count=u.getValue(); | 122 | Integer count=u.getValue(); | |
| 123 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | 123 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | |
| 124 | } | 124 | } | |
| 125 | } | 125 | } | |
| 126 | } | 126 | } | |
| 127 | } | 127 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_002 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_003 | |||
|---|---|---|---|---|
|
127 lines 5352 bytes Last modified : Mon May 14 20:27:08 2012 |
127 lines 5354 bytes Last modified : Mon May 14 20:27:08 2012 |
|||
| 1 | //Time : 2012-04-12 06:35:08.289 | 1 | //Time : 2012-04-12 06:35:09.539 | |
| 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.EnumMap; | 4 | import java.util.EnumMap; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Map; | 7 | import java.util.Map; | |
| 8 | import java.util.Map.Entry; | 8 | import java.util.Map.Entry; | |
| 9 | import java.util.Set; | 9 | import java.util.Set; | |
| 10 | import com.ibm.wala.types.FieldReference; | 10 | import com.ibm.wala.types.FieldReference; | |
| 11 | import com.ibm.wala.util.collections.Pair; | 11 | import com.ibm.wala.util.collections.Pair; | |
| 12 | import energy.components.Component; | 12 | import energy.components.Component; | |
| 13 | import energy.interproc.CompoundLockState; | 13 | import energy.interproc.CompoundLockState; | |
| 14 | import energy.interproc.SingleLockState; | 14 | import energy.interproc.SingleLockState; | |
| 15 | import energy.util.E; | 15 | import energy.util.E; | |
| 16 | public class AnalysisResults { | 16 | public class AnalysisResults { | |
| 17 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | 17 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | |
| 18 | public class ComponentResult { | 18 | public class ComponentResult { | |
| 19 | HashMap<String,CompoundLockState> callBackExitStates; | 19 | HashMap<String,CompoundLockState> callBackExitStates; | |
| 20 | public ComponentResult(){ | 20 | public ComponentResult(){ | |
| 21 | callBackExitStates=new HashMap<String,CompoundLockState>(); | 21 | callBackExitStates=new HashMap<String,CompoundLockState>(); | |
| 22 | } | 22 | } | |
| 23 | } | 23 | } | |
| 24 | /** | 24 | /** | |
| 25 | * The constructor | 25 | * The constructor | |
| 26 | */ | 26 | */ | |
| 27 | AnalysisResults(){ | 27 | AnalysisResults(){ | |
| 28 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | 28 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | |
| 29 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | 29 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | |
| 30 | } | 30 | } | |
| 31 | int threadCount=0; | 31 | int threadCount=0; | |
| 32 | int activityCount=0; | 32 | int activityCount=0; | |
| 33 | int lockThreads=0; | 33 | int lockThreads=0; | |
| 34 | int nolockThreads=0; | 34 | int nolockThreads=0; | |
| 35 | int unlockThreads=0; | 35 | int unlockThreads=0; | |
| 36 | int lockunlockThreads=0; | 36 | int lockunlockThreads=0; | |
| 37 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 37 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 38 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | 38 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | |
| 39 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | 39 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | |
| 40 | resultStuff.add(Pair.make(component,map)); | 40 | resultStuff.add(Pair.make(component,map)); | |
| 41 | StringBuffer sb=new StringBuffer(); | 41 | StringBuffer sb=new StringBuffer(); | |
| 42 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | 42 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | |
| 43 | if (e.getValue().size() > 0) { | 43 | if (e.getValue().size() > 0) { | |
| 44 | sb.append(e.getKey() + "\n"); | 44 | sb.append(e.getKey() + "\n"); | |
| 45 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | 45 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | |
| 46 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | 46 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | |
| 47 | } | 47 | } | |
| 48 | } | 48 | } | |
| 49 | } | 49 | } | |
| 50 | if (sb.length() > 0) { | 50 | if (sb.length() > 0) { | |
| 51 | E.log(1,component.toString() + "\n" + sb.toString()); | 51 | E.log(1,component.toString() + "\n" + sb.toString()); | |
| 52 | } | 52 | } | |
| 53 | } | 53 | } | |
| 54 | private LockUsage getLockUsage( SingleLockState runState){ | 54 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 55 | if (runState != null) { | 55 | if (runState != null) { | |
| 56 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 56 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 57 | return LockUsage.LOCKING; | 57 | return LockUsage.LOCKING; | |
| 58 | } | 58 | } | |
| 59 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 59 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 60 | return LockUsage.EMPTY; | 60 | return LockUsage.EMPTY; | |
| 61 | } | 61 | } | |
| 62 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 62 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 63 | return LockUsage.FULL_UNLOCKING; | 63 | return LockUsage.FULL_UNLOCKING; | |
| 64 | } | 64 | } | |
| 65 | else if (runState.isMaybeReleased()) { | 65 | else if (runState.isMaybeReleased()) { | |
| 66 | return LockUsage.UNLOCKING; | 66 | return LockUsage.UNLOCKING; | |
| 67 | } | 67 | } | |
| 68 | else { | 68 | else { | |
| 69 | return LockUsage.UNKNOWN_STATE; | 69 | return LockUsage.UNKNOWN_STATE; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | else { | 72 | else { | |
| 73 | return LockUsage.EMPTY; | 73 | return LockUsage.EMPTY; | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | public void processResults(){ | 76 | public void processResults(){ | |
| 77 | System.out.println(); | 77 | System.out.println(""); | |
| 78 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | 78 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | |
| 79 | Component component=pair.fst; | 79 | Component component=pair.fst; | |
| 80 | String componentName=component.getComponentName(); | 80 | String componentName=component.getComponentName(); | |
| 81 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | 81 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | |
| 82 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | 82 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | |
| 83 | String callBackName=e.getKey(); | 83 | String callBackName=e.getKey(); | |
| 84 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | 84 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | |
| 85 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | 85 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | |
| 86 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | 86 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | |
| 87 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | 87 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | |
| 88 | FieldReference field=fs.getKey(); | 88 | FieldReference field=fs.getKey(); | |
| 89 | Set<SingleLockState> sls=fs.getValue(); | 89 | Set<SingleLockState> sls=fs.getValue(); | |
| 90 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 90 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 91 | LockUsage lockUsage=getLockUsage(sl); | 91 | LockUsage lockUsage=getLockUsage(sl); | |
| 92 | lockUsages.put(field,lockUsage); | 92 | lockUsages.put(field,lockUsage); | |
| 93 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | 93 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | |
| 94 | if (lockUsage != LockUsage.EMPTY) { | 94 | if (lockUsage != LockUsage.EMPTY) { | |
| 95 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | 95 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | |
| 96 | } | 96 | } | |
| 97 | updateEnumMap(enumMap,lockUsage); | 97 | updateEnumMap(enumMap,lockUsage); | |
| 98 | } | 98 | } | |
| 99 | } | 99 | } | |
| 100 | } | 100 | } | |
| 101 | } | 101 | } | |
| 102 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | 102 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | |
| 103 | if (enumMap == null) { | 103 | if (enumMap == null) { | |
| 104 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | 104 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | |
| 105 | } | 105 | } | |
| 106 | Integer count=enumMap.get(lockUsage); | 106 | Integer count=enumMap.get(lockUsage); | |
| 107 | if (count == null) { | 107 | if (count == null) { | |
| 108 | count=new Integer(1); | 108 | count=new Integer(1); | |
| 109 | enumMap.put(lockUsage,count); | 109 | enumMap.put(lockUsage,count); | |
| 110 | } | 110 | } | |
| 111 | else { | 111 | else { | |
| 112 | enumMap.put(lockUsage,count + 1); | 112 | enumMap.put(lockUsage,count + 1); | |
| 113 | } | 113 | } | |
| 114 | } | 114 | } | |
| 115 | public void outputFinalResults(){ | 115 | public void outputFinalResults(){ | |
| 116 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | 116 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | |
| 117 | Pair<String,String> key=e.getKey(); | 117 | Pair<String,String> key=e.getKey(); | |
| 118 | E.log(1,key.toString()); | 118 | E.log(1,key.toString()); | |
| 119 | EnumMap<LockUsage,Integer> usages=e.getValue(); | 119 | EnumMap<LockUsage,Integer> usages=e.getValue(); | |
| 120 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | 120 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | |
| 121 | LockUsage usage=u.getKey(); | 121 | LockUsage usage=u.getKey(); | |
| 122 | Integer count=u.getValue(); | 122 | Integer count=u.getValue(); | |
| 123 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | 123 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | |
| 124 | } | 124 | } | |
| 125 | } | 125 | } | |
| 126 | } | 126 | } | |
| 127 | } | 127 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_003 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_004 | |||
|---|---|---|---|---|
|
127 lines 5354 bytes Last modified : Mon May 14 20:27:08 2012 |
127 lines 5356 bytes Last modified : Mon May 14 20:27:08 2012 |
|||
| 1 | //Time : 2012-04-12 06:35:09.539 | 1 | //Time : 2012-04-12 06:35:10.781 | |
| 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.EnumMap; | 4 | import java.util.EnumMap; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Map; | 7 | import java.util.Map; | |
| 8 | import java.util.Map.Entry; | 8 | import java.util.Map.Entry; | |
| 9 | import java.util.Set; | 9 | import java.util.Set; | |
| 10 | import com.ibm.wala.types.FieldReference; | 10 | import com.ibm.wala.types.FieldReference; | |
| 11 | import com.ibm.wala.util.collections.Pair; | 11 | import com.ibm.wala.util.collections.Pair; | |
| 12 | import energy.components.Component; | 12 | import energy.components.Component; | |
| 13 | import energy.interproc.CompoundLockState; | 13 | import energy.interproc.CompoundLockState; | |
| 14 | import energy.interproc.SingleLockState; | 14 | import energy.interproc.SingleLockState; | |
| 15 | import energy.util.E; | 15 | import energy.util.E; | |
| 16 | public class AnalysisResults { | 16 | public class AnalysisResults { | |
| 17 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | 17 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | |
| 18 | public class ComponentResult { | 18 | public class ComponentResult { | |
| 19 | HashMap<String,CompoundLockState> callBackExitStates; | 19 | HashMap<String,CompoundLockState> callBackExitStates; | |
| 20 | public ComponentResult(){ | 20 | public ComponentResult(){ | |
| 21 | callBackExitStates=new HashMap<String,CompoundLockState>(); | 21 | callBackExitStates=new HashMap<String,CompoundLockState>(); | |
| 22 | } | 22 | } | |
| 23 | } | 23 | } | |
| 24 | /** | 24 | /** | |
| 25 | * The constructor | 25 | * The constructor | |
| 26 | */ | 26 | */ | |
| 27 | AnalysisResults(){ | 27 | AnalysisResults(){ | |
| 28 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | 28 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | |
| 29 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | 29 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | |
| 30 | } | 30 | } | |
| 31 | int threadCount=0; | 31 | int threadCount=0; | |
| 32 | int activityCount=0; | 32 | int activityCount=0; | |
| 33 | int lockThreads=0; | 33 | int lockThreads=0; | |
| 34 | int nolockThreads=0; | 34 | int nolockThreads=0; | |
| 35 | int unlockThreads=0; | 35 | int unlockThreads=0; | |
| 36 | int lockunlockThreads=0; | 36 | int lockunlockThreads=0; | |
| 37 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 37 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 38 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | 38 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | |
| 39 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | 39 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | |
| 40 | resultStuff.add(Pair.make(component,map)); | 40 | resultStuff.add(Pair.make(component,map)); | |
| 41 | StringBuffer sb=new StringBuffer(); | 41 | StringBuffer sb=new StringBuffer(); | |
| 42 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | 42 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | |
| 43 | if (e.getValue().size() > 0) { | 43 | if (e.getValue().size() > 0) { | |
| 44 | sb.append(e.getKey() + "\n"); | 44 | sb.append(e.getKey() + "\n"); | |
| 45 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | 45 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | |
| 46 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | 46 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | |
| 47 | } | 47 | } | |
| 48 | } | 48 | } | |
| 49 | } | 49 | } | |
| 50 | if (sb.length() > 0) { | 50 | if (sb.length() > 0) { | |
| 51 | E.log(1,component.toString() + "\n" + sb.toString()); | 51 | E.log(1,component.toString() + "\n" + sb.toString()); | |
| 52 | } | 52 | } | |
| 53 | } | 53 | } | |
| 54 | private LockUsage getLockUsage( SingleLockState runState){ | 54 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 55 | if (runState != null) { | 55 | if (runState != null) { | |
| 56 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 56 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 57 | return LockUsage.LOCKING; | 57 | return LockUsage.LOCKING; | |
| 58 | } | 58 | } | |
| 59 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 59 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 60 | return LockUsage.EMPTY; | 60 | return LockUsage.EMPTY; | |
| 61 | } | 61 | } | |
| 62 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 62 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 63 | return LockUsage.FULL_UNLOCKING; | 63 | return LockUsage.FULL_UNLOCKING; | |
| 64 | } | 64 | } | |
| 65 | else if (runState.isMaybeReleased()) { | 65 | else if (runState.isMaybeReleased()) { | |
| 66 | return LockUsage.UNLOCKING; | 66 | return LockUsage.UNLOCKING; | |
| 67 | } | 67 | } | |
| 68 | else { | 68 | else { | |
| 69 | return LockUsage.UNKNOWN_STATE; | 69 | return LockUsage.UNKNOWN_STATE; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | else { | 72 | else { | |
| 73 | return LockUsage.EMPTY; | 73 | return LockUsage.EMPTY; | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | public void processResults(){ | 76 | public void processResults(){ | |
| 77 | System.out.println(""); | 77 | System.out.println("\n"); | |
| 78 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | 78 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | |
| 79 | Component component=pair.fst; | 79 | Component component=pair.fst; | |
| 80 | String componentName=component.getComponentName(); | 80 | String componentName=component.getComponentName(); | |
| 81 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | 81 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | |
| 82 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | 82 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | |
| 83 | String callBackName=e.getKey(); | 83 | String callBackName=e.getKey(); | |
| 84 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | 84 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | |
| 85 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | 85 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | |
| 86 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | 86 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | |
| 87 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | 87 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | |
| 88 | FieldReference field=fs.getKey(); | 88 | FieldReference field=fs.getKey(); | |
| 89 | Set<SingleLockState> sls=fs.getValue(); | 89 | Set<SingleLockState> sls=fs.getValue(); | |
| 90 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 90 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 91 | LockUsage lockUsage=getLockUsage(sl); | 91 | LockUsage lockUsage=getLockUsage(sl); | |
| 92 | lockUsages.put(field,lockUsage); | 92 | lockUsages.put(field,lockUsage); | |
| 93 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | 93 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | |
| 94 | if (lockUsage != LockUsage.EMPTY) { | 94 | if (lockUsage != LockUsage.EMPTY) { | |
| 95 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | 95 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | |
| 96 | } | 96 | } | |
| 97 | updateEnumMap(enumMap,lockUsage); | 97 | updateEnumMap(enumMap,lockUsage); | |
| 98 | } | 98 | } | |
| 99 | } | 99 | } | |
| 100 | } | 100 | } | |
| 101 | } | 101 | } | |
| 102 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | 102 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | |
| 103 | if (enumMap == null) { | 103 | if (enumMap == null) { | |
| 104 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | 104 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | |
| 105 | } | 105 | } | |
| 106 | Integer count=enumMap.get(lockUsage); | 106 | Integer count=enumMap.get(lockUsage); | |
| 107 | if (count == null) { | 107 | if (count == null) { | |
| 108 | count=new Integer(1); | 108 | count=new Integer(1); | |
| 109 | enumMap.put(lockUsage,count); | 109 | enumMap.put(lockUsage,count); | |
| 110 | } | 110 | } | |
| 111 | else { | 111 | else { | |
| 112 | enumMap.put(lockUsage,count + 1); | 112 | enumMap.put(lockUsage,count + 1); | |
| 113 | } | 113 | } | |
| 114 | } | 114 | } | |
| 115 | public void outputFinalResults(){ | 115 | public void outputFinalResults(){ | |
| 116 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | 116 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | |
| 117 | Pair<String,String> key=e.getKey(); | 117 | Pair<String,String> key=e.getKey(); | |
| 118 | E.log(1,key.toString()); | 118 | E.log(1,key.toString()); | |
| 119 | EnumMap<LockUsage,Integer> usages=e.getValue(); | 119 | EnumMap<LockUsage,Integer> usages=e.getValue(); | |
| 120 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | 120 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | |
| 121 | LockUsage usage=u.getKey(); | 121 | LockUsage usage=u.getKey(); | |
| 122 | Integer count=u.getValue(); | 122 | Integer count=u.getValue(); | |
| 123 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | 123 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | |
| 124 | } | 124 | } | |
| 125 | } | 125 | } | |
| 126 | } | 126 | } | |
| 127 | } | 127 | } |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_004 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_005 | |||
|---|---|---|---|---|
|
127 lines 5356 bytes Last modified : Mon May 14 20:27:08 2012 |
305 lines 11787 bytes Last modified : Mon May 14 20:27:48 2012 |
|||
| 1 | //Time : 2012-04-12 06:35:10.781 | 1 | //Time : 2012-04-24 18:21:38.377 | |
| 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.EnumMap; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | |||
| 7 | import java.util.Map; | 8 | import java.util.Map; | |
| 8 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 9 | import java.util.Set; | 10 | import java.util.Set; | |
| 10 | import com.ibm.wala.types.FieldReference; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 11 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |||
| 12 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | |||
| 13 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 14 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 15 | import energy.util.E; | 18 | import energy.util.E; | |
| 16 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 17 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | |||
| 18 | public class ComponentResult { | |||
| 19 | HashMap<String,CompoundLockState> callBackExitStates; | |||
| 20 | public ComponentResult(){ | |||
| 21 | callBackExitStates=new HashMap<String,CompoundLockState>(); | |||
| 22 | } | |||
| 23 | } | |||
| 24 | /** | 20 | /** | |
| 25 | * The constructor | 21 | * Main structures that hold the analysis results for every component | |
| 26 | */ | 22 | */ | |
| 27 | AnalysisResults(){ | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 28 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | 24 | public class ComponentSummary { | |
| 29 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | 25 | private Component component; | |
| 30 | } | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 31 | int threadCount=0; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 32 | int activityCount=0; | 28 | public ComponentSummary( Component c){ | |
| 33 | int lockThreads=0; | 29 | this.component=c; | |
| 34 | int nolockThreads=0; | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 35 | int unlockThreads=0; | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 36 | int lockunlockThreads=0; | 32 | } | |
| 37 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 38 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | 34 | return allExitStates; | |
| 39 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | 35 | } | |
| 40 | resultStuff.add(Pair.make(component,map)); | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 41 | StringBuffer sb=new StringBuffer(); | 37 | allExitStates.put(n,st); | |
| 42 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | 38 | } | |
| 43 | if (e.getValue().size() > 0) { | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 44 | sb.append(e.getKey() + "\n"); | 40 | callBackExitStates.put(cb,st); | |
| 45 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | 41 | } | |
| 46 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | |||
| 44 | } | |||
| 45 | public String toString(){ | |||
| 46 | StringBuffer sb=new StringBuffer(); | |||
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |||
| 48 | CGNode next=it.next(); | |||
| 49 | String name=next.getMethod().getName().toString(); | |||
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |||
| 51 | if (stateForMethod != null) { | |||
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |||
| 53 | } | |||
| 54 | } | |||
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |||
| 56 | if (callbacks != null) { | |||
| 57 | if (callbacks.size() > 0) { | |||
| 58 | sb.append("Callbacks:\n"); | |||
| 59 | for ( CallBack cb : callbacks) { | |||
| 60 | String name=cb.getName(); | |||
| 61 | ; | |||
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |||
| 63 | if (stateForMethod != null) { | |||
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |||
| 65 | } | |||
| 66 | } | |||
| 47 | } | 67 | } | |
| 48 | } | 68 | } | |
| 69 | return null; | |||
| 49 | } | 70 | } | |
| 50 | if (sb.length() > 0) { | 71 | } | |
| 51 | E.log(1,component.toString() + "\n" + sb.toString()); | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |||
| 74 | } | |||
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |||
| 76 | /** | |||
| 77 | * Invoke this after the component has been analyzed | |||
| 78 | * @param component | |||
| 79 | */ | |||
| 80 | public void createComponentSummary( Component component){ | |||
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |||
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |||
| 83 | CGNode next=it.next(); | |||
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |||
| 85 | if (exitState != null) { | |||
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |||
| 87 | componentSummary.registerNodeState(next,compoundLockState); | |||
| 88 | } | |||
| 52 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | |||
| 53 | } | 91 | } | |
| 54 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 55 | if (runState != null) { | 93 | if (runState != null) { | |
| 56 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 57 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 58 | } | 96 | } | |
| 59 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 60 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 61 | } | 99 | } | |
| 62 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 63 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 64 | } | 102 | } | |
| 65 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 66 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 67 | } | 105 | } | |
| 68 | else { | 106 | else { | |
| 69 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 70 | } | 108 | } | |
| 71 | } | 109 | } | |
| 72 | else { | 110 | else { | |
| 73 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 74 | } | 112 | } | |
| 75 | } | 113 | } | |
| 76 | public void processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 77 | System.out.println("\n"); | 115 | ArrayList<String> result=null; | |
| 78 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |||
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |||
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |||
| 79 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 80 | String componentName=component.getComponentName(); | 121 | ComponentSummary cSummary=pair.snd; | |
| 81 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 82 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | 123 | StringBuffer sb=new StringBuffer(); | |
| 83 | String callBackName=e.getKey(); | 124 | boolean printComponent=false; | |
| 84 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 85 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | 126 | CGNode node=e.getKey(); | |
| 86 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 87 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | 128 | boolean printMethod=false; | |
| 88 | FieldReference field=fs.getKey(); | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | |||
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |||
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |||
| 133 | WakeLockInstance wli=fs.getKey(); | |||
| 89 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 90 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 91 | LockUsage lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 92 | lockUsages.put(field,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 93 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | |||
| 94 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 95 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | 139 | printMethod=true; | |
| 96 | } | 140 | } | |
| 97 | updateEnumMap(enumMap,lockUsage); | |||
| 98 | } | 141 | } | |
| 142 | if (printMethod) { | |||
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |||
| 144 | printComponent=true; | |||
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |||
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |||
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |||
| 148 | WakeLockInstance key=fs.getKey(); | |||
| 149 | Set<SingleLockState> value=fs.getValue(); | |||
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |||
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |||
| 152 | } | |||
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |||
| 154 | LockUsage lu=getLockUsage(mergedLS); | |||
| 155 | if (component.isCallBack(node)) { | |||
| 156 | if (usageMap.containsKey(lu)) { | |||
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | |||
| 158 | } | |||
| 159 | else { | |||
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |||
| 161 | set.add(Pair.make(component,node)); | |||
| 162 | usageMap.put(lu,set); | |||
| 163 | } | |||
| 164 | policy.addFact(node,mergedLS); | |||
| 165 | } | |||
| 166 | } | |||
| 167 | } | |||
| 168 | } | |||
| 169 | if (printComponent) { | |||
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |||
| 171 | policy.solveFacts(); | |||
| 172 | componentMap.put(component,policy.getLogger()); | |||
| 99 | } | 173 | } | |
| 100 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | |||
| 176 | for ( LockUsage e : usageMap.keySet()) { | |||
| 177 | System.out.println(e.toString()); | |||
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |||
| 179 | System.out.println(" " + s.toString()); | |||
| 180 | } | |||
| 181 | } | |||
| 182 | System.out.println("==========================================\n"); | |||
| 183 | for ( Component e : componentMap.keySet()) { | |||
| 184 | Logger logger=componentMap.get(e); | |||
| 185 | if (!logger.isEmpty()) { | |||
| 186 | System.out.println(e.toString()); | |||
| 187 | System.out.println(logger.toString()); | |||
| 188 | System.out.println("\n"); | |||
| 189 | } | |||
| 190 | result=logger.getStringList(); | |||
| 191 | } | |||
| 192 | return result; | |||
| 101 | } | 193 | } | |
| 102 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | 194 | public class Logger extends ArrayList<String> { | |
| 103 | if (enumMap == null) { | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 104 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | 196 | public void output(){ | |
| 197 | for ( String s : this) { | |||
| 198 | System.out.println(" " + s); | |||
| 199 | } | |||
| 105 | } | 200 | } | |
| 106 | Integer count=enumMap.get(lockUsage); | 201 | public ArrayList<String> getStringList(){ | |
| 107 | if (count == null) { | 202 | return this; | |
| 108 | count=new Integer(1); | |||
| 109 | enumMap.put(lockUsage,count); | |||
| 110 | } | 203 | } | |
| 111 | else { | 204 | public String toString(){ | |
| 112 | enumMap.put(lockUsage,count + 1); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | |||
| 207 | result.append(s + "\n"); | |||
| 208 | } | |||
| 209 | return result.toString(); | |||
| 113 | } | 210 | } | |
| 114 | } | 211 | } | |
| 115 | public void outputFinalResults(){ | 212 | public class ComponentPolicy { | |
| 116 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | 213 | private Component component; | |
| 117 | Pair<String,String> key=e.getKey(); | 214 | public ComponentPolicy( Component component){ | |
| 118 | E.log(1,key.toString()); | 215 | this.component=component; | |
| 119 | EnumMap<LockUsage,Integer> usages=e.getValue(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 120 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | 217 | logger=new Logger(); | |
| 121 | LockUsage usage=u.getKey(); | 218 | } | |
| 122 | Integer count=u.getValue(); | 219 | private HashMap<String,SingleLockState> map; | |
| 123 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | |||
| 222 | } | |||
| 223 | private boolean unlocking( SingleLockState state){ | |||
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |||
| 225 | } | |||
| 226 | private boolean strongUnlocking( SingleLockState state){ | |||
| 227 | if (state != null) { | |||
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |||
| 229 | } | |||
| 230 | return false; | |||
| 231 | } | |||
| 232 | private boolean weakUnlocking( SingleLockState state){ | |||
| 233 | if (state != null) { | |||
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |||
| 235 | } | |||
| 236 | return false; | |||
| 237 | } | |||
| 238 | private boolean locking( SingleLockState onCreateState){ | |||
| 239 | if (onCreateState != null) { | |||
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |||
| 241 | } | |||
| 242 | return false; | |||
| 243 | } | |||
| 244 | private Logger logger; | |||
| 245 | private void logNote( String s){ | |||
| 246 | logger.add(s); | |||
| 247 | } | |||
| 248 | public Logger getLogger(){ | |||
| 249 | return logger; | |||
| 250 | } | |||
| 251 | private SingleLockState getServiceOnStart(){ | |||
| 252 | SingleLockState onStart=map.get("onStart"); | |||
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |||
| 254 | if (onStartCommand == null) { | |||
| 255 | return onStart; | |||
| 256 | } | |||
| 257 | else { | |||
| 258 | return onStartCommand; | |||
| 259 | } | |||
| 260 | } | |||
| 261 | /** | |||
| 262 | * TODO: make sure the same lock is locked and unlocked... | |||
| 263 | */ | |||
| 264 | public void solveFacts(){ | |||
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | |||
| 266 | if (component.getComponentType().equals("Activity")) { | |||
| 267 | SingleLockState onCreateState=map.get("onCreate"); | |||
| 268 | if (locking(onCreateState)) { | |||
| 269 | logNote("STRONG BUG: Locking @ onCreate"); | |||
| 270 | } | |||
| 271 | SingleLockState onStartState=map.get("onStart"); | |||
| 272 | if (locking(onStartState)) { | |||
| 273 | logNote("POSSIBLE BUG: Locking @ onStart"); | |||
| 274 | } | |||
| 275 | SingleLockState onPauseState=map.get("onPause"); | |||
| 276 | SingleLockState onResumeState=map.get("onResume"); | |||
| 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |||
| 278 | logNote("POSSIBLE BUG(onPause - onResume)"); | |||
| 279 | } | |||
| 280 | } | |||
| 281 | if (component.getComponentType().equals("Service")) { | |||
| 282 | SingleLockState onStartState=getServiceOnStart(); | |||
| 283 | SingleLockState onDestroyState=map.get("onDestroy"); | |||
| 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |||
| 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |||
| 286 | } | |||
| 287 | if (weakUnlocking(onDestroyState)) { | |||
| 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |||
| 289 | } | |||
| 290 | } | |||
| 291 | if (component.getComponentType().equals("RunnableThread")) { | |||
| 292 | SingleLockState runState=map.get("run"); | |||
| 293 | if (locking(runState)) { | |||
| 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |||
| 295 | } | |||
| 296 | } | |||
| 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | |||
| 298 | SingleLockState onReceiveState=map.get("onReceive"); | |||
| 299 | if (locking(onReceiveState)) { | |||
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |||
| 301 | } | |||
| 124 | } | 302 | } | |
| 125 | } | 303 | } | |
| 126 | } | 304 | } | |
| 127 | } | 305 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_005 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_006 | |||
|---|---|---|---|---|
|
305 lines 11787 bytes Last modified : Mon May 14 20:27:48 2012 |
305 lines 11785 bytes Last modified : Mon May 14 20:27:48 2012 |
|||
| 1 | //Time : 2012-04-24 18:21:38.377 | 1 | //Time : 2012-04-24 18:21:42.137 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate"); | 269 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("POSSIBLE BUG: Locking @ onStart"); | 273 | logNote("STRONG BUG: Locking @ onStart"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onPauseState=map.get("onPause"); | 275 | SingleLockState onPauseState=map.get("onPause"); | |
| 276 | SingleLockState onResumeState=map.get("onResume"); | 276 | SingleLockState onResumeState=map.get("onResume"); | |
| 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 278 | logNote("POSSIBLE BUG(onPause - onResume)"); | 278 | logNote("POSSIBLE BUG(onPause - onResume)"); | |
| 279 | } | 279 | } | |
| 280 | } | 280 | } | |
| 281 | if (component.getComponentType().equals("Service")) { | 281 | if (component.getComponentType().equals("Service")) { | |
| 282 | SingleLockState onStartState=getServiceOnStart(); | 282 | SingleLockState onStartState=getServiceOnStart(); | |
| 283 | SingleLockState onDestroyState=map.get("onDestroy"); | 283 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 286 | } | 286 | } | |
| 287 | if (weakUnlocking(onDestroyState)) { | 287 | if (weakUnlocking(onDestroyState)) { | |
| 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 289 | } | 289 | } | |
| 290 | } | 290 | } | |
| 291 | if (component.getComponentType().equals("RunnableThread")) { | 291 | if (component.getComponentType().equals("RunnableThread")) { | |
| 292 | SingleLockState runState=map.get("run"); | 292 | SingleLockState runState=map.get("run"); | |
| 293 | if (locking(runState)) { | 293 | if (locking(runState)) { | |
| 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 295 | } | 295 | } | |
| 296 | } | 296 | } | |
| 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 298 | SingleLockState onReceiveState=map.get("onReceive"); | 298 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 299 | if (locking(onReceiveState)) { | 299 | if (locking(onReceiveState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | } | 305 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_006 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_007 | |||
|---|---|---|---|---|
|
305 lines 11785 bytes Last modified : Mon May 14 20:27:48 2012 |
305 lines 11783 bytes Last modified : Mon May 14 20:27:48 2012 |
|||
| 1 | //Time : 2012-04-24 18:21:42.137 | 1 | //Time : 2012-04-24 18:21:49.371 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate"); | 269 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart"); | 273 | logNote("STRONG BUG: Locking @ onStart"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onPauseState=map.get("onPause"); | 275 | SingleLockState onPauseState=map.get("onPause"); | |
| 276 | SingleLockState onResumeState=map.get("onResume"); | 276 | SingleLockState onResumeState=map.get("onResume"); | |
| 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 278 | logNote("POSSIBLE BUG(onPause - onResume)"); | 278 | logNote("STRONG BUG(onPause - onResume)"); | |
| 279 | } | 279 | } | |
| 280 | } | 280 | } | |
| 281 | if (component.getComponentType().equals("Service")) { | 281 | if (component.getComponentType().equals("Service")) { | |
| 282 | SingleLockState onStartState=getServiceOnStart(); | 282 | SingleLockState onStartState=getServiceOnStart(); | |
| 283 | SingleLockState onDestroyState=map.get("onDestroy"); | 283 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 286 | } | 286 | } | |
| 287 | if (weakUnlocking(onDestroyState)) { | 287 | if (weakUnlocking(onDestroyState)) { | |
| 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 289 | } | 289 | } | |
| 290 | } | 290 | } | |
| 291 | if (component.getComponentType().equals("RunnableThread")) { | 291 | if (component.getComponentType().equals("RunnableThread")) { | |
| 292 | SingleLockState runState=map.get("run"); | 292 | SingleLockState runState=map.get("run"); | |
| 293 | if (locking(runState)) { | 293 | if (locking(runState)) { | |
| 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 295 | } | 295 | } | |
| 296 | } | 296 | } | |
| 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 298 | SingleLockState onReceiveState=map.get("onReceive"); | 298 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 299 | if (locking(onReceiveState)) { | 299 | if (locking(onReceiveState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | } | 305 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_007 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_008 | |||
|---|---|---|---|---|
|
305 lines 11783 bytes Last modified : Mon May 14 20:27:48 2012 |
305 lines 11784 bytes Last modified : Mon May 14 20:27:48 2012 |
|||
| 1 | //Time : 2012-04-24 18:21:49.371 | 1 | //Time : 2012-04-24 18:21:54.118 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate"); | 269 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart"); | 273 | logNote("STRONG BUG: Locking @ onStart"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onPauseState=map.get("onPause"); | 275 | SingleLockState onPauseState=map.get("onPause"); | |
| 276 | SingleLockState onResumeState=map.get("onResume"); | 276 | SingleLockState onResumeState=map.get("onResume"); | |
| 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 278 | logNote("STRONG BUG(onPause - onResume)"); | 278 | logNote("STRONG BUG: onPause - onResume)"); | |
| 279 | } | 279 | } | |
| 280 | } | 280 | } | |
| 281 | if (component.getComponentType().equals("Service")) { | 281 | if (component.getComponentType().equals("Service")) { | |
| 282 | SingleLockState onStartState=getServiceOnStart(); | 282 | SingleLockState onStartState=getServiceOnStart(); | |
| 283 | SingleLockState onDestroyState=map.get("onDestroy"); | 283 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 286 | } | 286 | } | |
| 287 | if (weakUnlocking(onDestroyState)) { | 287 | if (weakUnlocking(onDestroyState)) { | |
| 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 289 | } | 289 | } | |
| 290 | } | 290 | } | |
| 291 | if (component.getComponentType().equals("RunnableThread")) { | 291 | if (component.getComponentType().equals("RunnableThread")) { | |
| 292 | SingleLockState runState=map.get("run"); | 292 | SingleLockState runState=map.get("run"); | |
| 293 | if (locking(runState)) { | 293 | if (locking(runState)) { | |
| 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 295 | } | 295 | } | |
| 296 | } | 296 | } | |
| 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 298 | SingleLockState onReceiveState=map.get("onReceive"); | 298 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 299 | if (locking(onReceiveState)) { | 299 | if (locking(onReceiveState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | } | 305 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_008 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_009 | |||
|---|---|---|---|---|
|
305 lines 11784 bytes Last modified : Mon May 14 20:27:48 2012 |
305 lines 11783 bytes Last modified : Mon May 14 20:27:48 2012 |
|||
| 1 | //Time : 2012-04-24 18:21:54.118 | 1 | //Time : 2012-04-24 18:21:55.584 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate"); | 269 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart"); | 273 | logNote("STRONG BUG: Locking @ onStart"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onPauseState=map.get("onPause"); | 275 | SingleLockState onPauseState=map.get("onPause"); | |
| 276 | SingleLockState onResumeState=map.get("onResume"); | 276 | SingleLockState onResumeState=map.get("onResume"); | |
| 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 278 | logNote("STRONG BUG: onPause - onResume)"); | 278 | logNote("STRONG BUG: onPause - onResume"); | |
| 279 | } | 279 | } | |
| 280 | } | 280 | } | |
| 281 | if (component.getComponentType().equals("Service")) { | 281 | if (component.getComponentType().equals("Service")) { | |
| 282 | SingleLockState onStartState=getServiceOnStart(); | 282 | SingleLockState onStartState=getServiceOnStart(); | |
| 283 | SingleLockState onDestroyState=map.get("onDestroy"); | 283 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 286 | } | 286 | } | |
| 287 | if (weakUnlocking(onDestroyState)) { | 287 | if (weakUnlocking(onDestroyState)) { | |
| 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 289 | } | 289 | } | |
| 290 | } | 290 | } | |
| 291 | if (component.getComponentType().equals("RunnableThread")) { | 291 | if (component.getComponentType().equals("RunnableThread")) { | |
| 292 | SingleLockState runState=map.get("run"); | 292 | SingleLockState runState=map.get("run"); | |
| 293 | if (locking(runState)) { | 293 | if (locking(runState)) { | |
| 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 295 | } | 295 | } | |
| 296 | } | 296 | } | |
| 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 298 | SingleLockState onReceiveState=map.get("onReceive"); | 298 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 299 | if (locking(onReceiveState)) { | 299 | if (locking(onReceiveState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | } | 305 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_009 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_010 | |||
|---|---|---|---|---|
|
305 lines 11783 bytes Last modified : Mon May 14 20:27:48 2012 |
305 lines 11786 bytes Last modified : Mon May 14 20:27:48 2012 |
|||
| 1 | //Time : 2012-04-24 18:21:55.584 | 1 | //Time : 2012-04-24 18:22:00.338 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate"); | 269 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart"); | 273 | logNote("STRONG BUG: Locking @ onStart"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onPauseState=map.get("onPause"); | 275 | SingleLockState onPauseState=map.get("onPause"); | |
| 276 | SingleLockState onResumeState=map.get("onResume"); | 276 | SingleLockState onResumeState=map.get("onResume"); | |
| 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 278 | logNote("STRONG BUG: onPause - onResume"); | 278 | logNote("STRONG BUG: onPause - onResume ()"); | |
| 279 | } | 279 | } | |
| 280 | } | 280 | } | |
| 281 | if (component.getComponentType().equals("Service")) { | 281 | if (component.getComponentType().equals("Service")) { | |
| 282 | SingleLockState onStartState=getServiceOnStart(); | 282 | SingleLockState onStartState=getServiceOnStart(); | |
| 283 | SingleLockState onDestroyState=map.get("onDestroy"); | 283 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 286 | } | 286 | } | |
| 287 | if (weakUnlocking(onDestroyState)) { | 287 | if (weakUnlocking(onDestroyState)) { | |
| 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 289 | } | 289 | } | |
| 290 | } | 290 | } | |
| 291 | if (component.getComponentType().equals("RunnableThread")) { | 291 | if (component.getComponentType().equals("RunnableThread")) { | |
| 292 | SingleLockState runState=map.get("run"); | 292 | SingleLockState runState=map.get("run"); | |
| 293 | if (locking(runState)) { | 293 | if (locking(runState)) { | |
| 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 295 | } | 295 | } | |
| 296 | } | 296 | } | |
| 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 298 | SingleLockState onReceiveState=map.get("onReceive"); | 298 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 299 | if (locking(onReceiveState)) { | 299 | if (locking(onReceiveState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | } | 305 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_010 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_011 | |||
|---|---|---|---|---|
|
305 lines 11786 bytes Last modified : Mon May 14 20:27:48 2012 |
305 lines 11785 bytes Last modified : Mon May 14 20:27:48 2012 |
|||
| 1 | //Time : 2012-04-24 18:22:00.338 | 1 | //Time : 2012-04-24 18:22:02.144 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate"); | 269 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart"); | 273 | logNote("STRONG BUG: Locking @ onStart"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onPauseState=map.get("onPause"); | 275 | SingleLockState onPauseState=map.get("onPause"); | |
| 276 | SingleLockState onResumeState=map.get("onResume"); | 276 | SingleLockState onResumeState=map.get("onResume"); | |
| 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 278 | logNote("STRONG BUG: onPause - onResume ()"); | 278 | logNote("STRONG BUG: onPause - onResume ("); | |
| 279 | } | 279 | } | |
| 280 | } | 280 | } | |
| 281 | if (component.getComponentType().equals("Service")) { | 281 | if (component.getComponentType().equals("Service")) { | |
| 282 | SingleLockState onStartState=getServiceOnStart(); | 282 | SingleLockState onStartState=getServiceOnStart(); | |
| 283 | SingleLockState onDestroyState=map.get("onDestroy"); | 283 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 286 | } | 286 | } | |
| 287 | if (weakUnlocking(onDestroyState)) { | 287 | if (weakUnlocking(onDestroyState)) { | |
| 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 289 | } | 289 | } | |
| 290 | } | 290 | } | |
| 291 | if (component.getComponentType().equals("RunnableThread")) { | 291 | if (component.getComponentType().equals("RunnableThread")) { | |
| 292 | SingleLockState runState=map.get("run"); | 292 | SingleLockState runState=map.get("run"); | |
| 293 | if (locking(runState)) { | 293 | if (locking(runState)) { | |
| 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 295 | } | 295 | } | |
| 296 | } | 296 | } | |
| 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 298 | SingleLockState onReceiveState=map.get("onReceive"); | 298 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 299 | if (locking(onReceiveState)) { | 299 | if (locking(onReceiveState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | } | 305 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_011 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_012 | |||
|---|---|---|---|---|
|
305 lines 11785 bytes Last modified : Mon May 14 20:27:48 2012 |
305 lines 11814 bytes Last modified : Mon May 14 20:27:48 2012 |
|||
| 1 | //Time : 2012-04-24 18:22:02.144 | 1 | //Time : 2012-04-24 18:22:06.889 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate"); | 269 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart"); | 273 | logNote("STRONG BUG: Locking @ onStart"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onPauseState=map.get("onPause"); | 275 | SingleLockState onPauseState=map.get("onPause"); | |
| 276 | SingleLockState onResumeState=map.get("onResume"); | 276 | SingleLockState onResumeState=map.get("onResume"); | |
| 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 278 | logNote("STRONG BUG: onPause - onResume ("); | 278 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 279 | } | 279 | } | |
| 280 | } | 280 | } | |
| 281 | if (component.getComponentType().equals("Service")) { | 281 | if (component.getComponentType().equals("Service")) { | |
| 282 | SingleLockState onStartState=getServiceOnStart(); | 282 | SingleLockState onStartState=getServiceOnStart(); | |
| 283 | SingleLockState onDestroyState=map.get("onDestroy"); | 283 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 286 | } | 286 | } | |
| 287 | if (weakUnlocking(onDestroyState)) { | 287 | if (weakUnlocking(onDestroyState)) { | |
| 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 289 | } | 289 | } | |
| 290 | } | 290 | } | |
| 291 | if (component.getComponentType().equals("RunnableThread")) { | 291 | if (component.getComponentType().equals("RunnableThread")) { | |
| 292 | SingleLockState runState=map.get("run"); | 292 | SingleLockState runState=map.get("run"); | |
| 293 | if (locking(runState)) { | 293 | if (locking(runState)) { | |
| 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 295 | } | 295 | } | |
| 296 | } | 296 | } | |
| 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 298 | SingleLockState onReceiveState=map.get("onReceive"); | 298 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 299 | if (locking(onReceiveState)) { | 299 | if (locking(onReceiveState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | } | 305 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_012 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_013 | |||
|---|---|---|---|---|
|
305 lines 11814 bytes Last modified : Mon May 14 20:27:48 2012 |
305 lines 11845 bytes Last modified : Mon May 14 20:27:48 2012 |
|||
| 1 | //Time : 2012-04-24 18:22:06.889 | 1 | //Time : 2012-04-24 18:22:28.193 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate"); | 269 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onPauseState=map.get("onPause"); | 275 | SingleLockState onPauseState=map.get("onPause"); | |
| 276 | SingleLockState onResumeState=map.get("onResume"); | 276 | SingleLockState onResumeState=map.get("onResume"); | |
| 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 278 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 278 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 279 | } | 279 | } | |
| 280 | } | 280 | } | |
| 281 | if (component.getComponentType().equals("Service")) { | 281 | if (component.getComponentType().equals("Service")) { | |
| 282 | SingleLockState onStartState=getServiceOnStart(); | 282 | SingleLockState onStartState=getServiceOnStart(); | |
| 283 | SingleLockState onDestroyState=map.get("onDestroy"); | 283 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 286 | } | 286 | } | |
| 287 | if (weakUnlocking(onDestroyState)) { | 287 | if (weakUnlocking(onDestroyState)) { | |
| 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 289 | } | 289 | } | |
| 290 | } | 290 | } | |
| 291 | if (component.getComponentType().equals("RunnableThread")) { | 291 | if (component.getComponentType().equals("RunnableThread")) { | |
| 292 | SingleLockState runState=map.get("run"); | 292 | SingleLockState runState=map.get("run"); | |
| 293 | if (locking(runState)) { | 293 | if (locking(runState)) { | |
| 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 295 | } | 295 | } | |
| 296 | } | 296 | } | |
| 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 298 | SingleLockState onReceiveState=map.get("onReceive"); | 298 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 299 | if (locking(onReceiveState)) { | 299 | if (locking(onReceiveState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | } | 305 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_013 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_015 | |||
|---|---|---|---|---|
|
305 lines 11845 bytes Last modified : Mon May 14 20:27:48 2012 |
305 lines 11876 bytes Last modified : Mon May 14 20:27:48 2012 |
|||
| 1 | //Time : 2012-04-24 18:22:28.193 | 1 | //Time : 2012-04-24 18:22:31.743 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onPauseState=map.get("onPause"); | 275 | SingleLockState onPauseState=map.get("onPause"); | |
| 276 | SingleLockState onResumeState=map.get("onResume"); | 276 | SingleLockState onResumeState=map.get("onResume"); | |
| 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 278 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 278 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 279 | } | 279 | } | |
| 280 | } | 280 | } | |
| 281 | if (component.getComponentType().equals("Service")) { | 281 | if (component.getComponentType().equals("Service")) { | |
| 282 | SingleLockState onStartState=getServiceOnStart(); | 282 | SingleLockState onStartState=getServiceOnStart(); | |
| 283 | SingleLockState onDestroyState=map.get("onDestroy"); | 283 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 286 | } | 286 | } | |
| 287 | if (weakUnlocking(onDestroyState)) { | 287 | if (weakUnlocking(onDestroyState)) { | |
| 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 289 | } | 289 | } | |
| 290 | } | 290 | } | |
| 291 | if (component.getComponentType().equals("RunnableThread")) { | 291 | if (component.getComponentType().equals("RunnableThread")) { | |
| 292 | SingleLockState runState=map.get("run"); | 292 | SingleLockState runState=map.get("run"); | |
| 293 | if (locking(runState)) { | 293 | if (locking(runState)) { | |
| 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 295 | } | 295 | } | |
| 296 | } | 296 | } | |
| 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 298 | SingleLockState onReceiveState=map.get("onReceive"); | 298 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 299 | if (locking(onReceiveState)) { | 299 | if (locking(onReceiveState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | } | 305 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_015 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_016 | |||
|---|---|---|---|---|
|
305 lines 11876 bytes Last modified : Mon May 14 20:27:48 2012 |
309 lines 12063 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 18:22:31.743 | 1 | //Time : 2012-04-24 18:27:17.387 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onStartState=map.get("onStart"); | |||
| 276 | if (locking(onStartState)) { | |||
| 277 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |||
| 278 | } | |||
| 275 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 276 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 278 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 279 | } | 283 | } | |
| 280 | } | 284 | } | |
| 281 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 282 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 283 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 286 | } | 290 | } | |
| 287 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 289 | } | 293 | } | |
| 290 | } | 294 | } | |
| 291 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 292 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 293 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 295 | } | 299 | } | |
| 296 | } | 300 | } | |
| 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | 301 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 298 | SingleLockState onReceiveState=map.get("onReceive"); | 302 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 299 | if (locking(onReceiveState)) { | 303 | if (locking(onReceiveState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 301 | } | 305 | } | |
| 302 | } | 306 | } | |
| 303 | } | 307 | } | |
| 304 | } | 308 | } | |
| 305 | } | 309 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_016 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_017 | |||
|---|---|---|---|---|
|
309 lines 12063 bytes Last modified : Mon May 14 20:27:49 2012 |
309 lines 12065 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 18:27:17.387 | 1 | //Time : 2012-04-24 18:27:20.898 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onStartState=map.get("onStart"); | 275 | SingleLockState onReStartState=map.get("onStart"); | |
| 276 | if (locking(onStartState)) { | 276 | if (locking(onStartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("BroadcastReceiver")) { | 301 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 302 | SingleLockState onReceiveState=map.get("onReceive"); | 302 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 303 | if (locking(onReceiveState)) { | 303 | if (locking(onReceiveState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_017 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_018 | |||
|---|---|---|---|---|
|
309 lines 12065 bytes Last modified : Mon May 14 20:27:49 2012 |
309 lines 12065 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 18:27:20.898 | 1 | //Time : 2012-04-24 18:27:22.145 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onReStartState=map.get("onStart"); | 275 | SingleLockState onRestartState=map.get("onStart"); | |
| 276 | if (locking(onStartState)) { | 276 | if (locking(onStartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("BroadcastReceiver")) { | 301 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 302 | SingleLockState onReceiveState=map.get("onReceive"); | 302 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 303 | if (locking(onReceiveState)) { | 303 | if (locking(onReceiveState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_018 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_019 | |||
|---|---|---|---|---|
|
309 lines 12065 bytes Last modified : Mon May 14 20:27:49 2012 |
309 lines 12067 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 18:27:22.145 | 1 | //Time : 2012-04-24 18:27:25.426 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onStart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onStartState)) { | 276 | if (locking(onStartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("BroadcastReceiver")) { | 301 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 302 | SingleLockState onReceiveState=map.get("onReceive"); | 302 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 303 | if (locking(onReceiveState)) { | 303 | if (locking(onReceiveState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_019 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_020 | |||
|---|---|---|---|---|
|
309 lines 12067 bytes Last modified : Mon May 14 20:27:49 2012 |
309 lines 12069 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 18:27:25.426 | 1 | //Time : 2012-04-24 18:27:32.177 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onStartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("BroadcastReceiver")) { | 301 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 302 | SingleLockState onReceiveState=map.get("onReceive"); | 302 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 303 | if (locking(onReceiveState)) { | 303 | if (locking(onReceiveState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_020 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_021 | |||
|---|---|---|---|---|
|
309 lines 12069 bytes Last modified : Mon May 14 20:27:49 2012 |
309 lines 12071 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 18:27:32.177 | 1 | //Time : 2012-04-24 18:27:37.462 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("BroadcastReceiver")) { | 301 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 302 | SingleLockState onReceiveState=map.get("onReceive"); | 302 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 303 | if (locking(onReceiveState)) { | 303 | if (locking(onReceiveState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_021 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_022 | |||
|---|---|---|---|---|
|
309 lines 12071 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12596 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 18:27:37.462 | 1 | //Time : 2012-04-24 19:01:34.462 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("RunnableThread")) { | |||
| 302 | SingleLockState runState=map.get("run"); | |||
| 303 | if (locking(runState)) { | |||
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |||
| 305 | } | |||
| 306 | } | |||
| 301 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 302 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 303 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 305 | } | 311 | } | |
| 306 | } | 312 | } | |
| 307 | } | 313 | } | |
| 308 | } | 314 | } | |
| 309 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_022 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_023 | |||
|---|---|---|---|---|
|
315 lines 12596 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12589 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:01:34.462 | 1 | //Time : 2012-04-24 19:01:41.521 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("RunnableThread")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("run"); | 302 | SingleLockState runState=map.get("run"); | |
| 303 | if (locking(runState)) { | 303 | if (locking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_023 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_024 | |||
|---|---|---|---|---|
|
315 lines 12589 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12592 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:01:41.521 | 1 | //Time : 2012-04-24 19:01:44.800 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("run"); | 302 | SingleLockState runState=map.get("handle"); | |
| 303 | if (locking(runState)) { | 303 | if (locking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_024 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_025 | |||
|---|---|---|---|---|
|
315 lines 12592 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12599 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:01:44.800 | 1 | //Time : 2012-04-24 19:01:48.592 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handle"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (locking(runState)) { | 303 | if (locking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_025 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_026 | |||
|---|---|---|---|---|
|
315 lines 12599 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12600 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:01:48.592 | 1 | //Time : 2012-04-24 19:02:05.916 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (locking(runState)) { | 303 | if (flocking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_026 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_027 | |||
|---|---|---|---|---|
|
315 lines 12600 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12603 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:05.916 | 1 | //Time : 2012-04-24 19:02:08.262 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (flocking(runState)) { | 303 | if (fulllocking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_027 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_028 | |||
|---|---|---|---|---|
|
315 lines 12603 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12599 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:08.262 | 1 | //Time : 2012-04-24 19:02:10.551 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (fulllocking(runState)) { | 303 | if (locking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_028 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_029 | |||
|---|---|---|---|---|
|
315 lines 12599 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12601 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:10.551 | 1 | //Time : 2012-04-24 19:02:12.861 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (locking(runState)) { | 303 | if (unlocking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_029 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_030 | |||
|---|---|---|---|---|
|
315 lines 12601 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12608 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:12.861 | 1 | //Time : 2012-04-24 19:02:19.167 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (unlocking(runState)) { | 303 | if (stroingunlocking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_030 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_031 | |||
|---|---|---|---|---|
|
315 lines 12608 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12609 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:19.167 | 1 | //Time : 2012-04-24 19:02:20.513 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (stroingunlocking(runState)) { | 303 | if (!stroingunlocking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_031 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_032 | |||
|---|---|---|---|---|
|
315 lines 12609 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12608 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:20.513 | 1 | //Time : 2012-04-24 19:02:22.285 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (!stroingunlocking(runState)) { | 303 | if (!strongunlocking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_032 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_033 | |||
|---|---|---|---|---|
|
315 lines 12608 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12607 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:22.285 | 1 | //Time : 2012-04-24 19:02:23.556 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (!strongunlocking(runState)) { | 303 | if (!strongnlocking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_033 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_034 | |||
|---|---|---|---|---|
|
315 lines 12607 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12618 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:23.556 | 1 | //Time : 2012-04-24 19:02:26.816 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (!strongnlocking(runState)) { | 303 | if (!strongUnlocking(state) * (runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_034 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_035 | |||
|---|---|---|---|---|
|
315 lines 12618 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12608 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:26.816 | 1 | //Time : 2012-04-24 19:02:29.611 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (!strongUnlocking(state) * (runState)) { | 303 | if (!strongUnlocking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_035 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_036 | |||
|---|---|---|---|---|
|
315 lines 12608 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12627 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:29.611 | 1 | //Time : 2012-04-24 19:02:34.974 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (!strongUnlocking(runState)) { | 303 | if (unlocking(state) != strongUnlocking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_036 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_037 | |||
|---|---|---|---|---|
|
315 lines 12627 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12630 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:34.974 | 1 | //Time : 2012-04-24 19:02:38.238 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (unlocking(state) != strongUnlocking(runState)) { | 303 | if (unlocking(runState) != strongUnlocking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_037 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_038 | |||
|---|---|---|---|---|
|
315 lines 12630 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12637 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:38.238 | 1 | //Time : 2012-04-24 19:02:41.064 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (unlocking(runState) != strongUnlocking(runState)) { | 303 | if (unlocking(runState) && (void)!strongUnlocking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_038 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_039 | |||
|---|---|---|---|---|
|
315 lines 12637 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12633 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:41.064 | 1 | //Time : 2012-04-24 19:02:43.406 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (unlocking(runState) && (void)!strongUnlocking(runState)) { | 303 | if (unlocking(runState) && (!strongUnlocking(runState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_039 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_040 | |||
|---|---|---|---|---|
|
315 lines 12633 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12631 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:43.406 | 1 | //Time : 2012-04-24 19:02:47.732 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (unlocking(runState) && (!strongUnlocking(runState))) { | 303 | if (unlocking(runState) && !strongUnlocking(runState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_040 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_041 | |||
|---|---|---|---|---|
|
315 lines 12631 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12633 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:47.732 | 1 | //Time : 2012-04-24 19:02:49.537 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState runState=map.get("handleMessage"); | |
| 303 | if (unlocking(runState) && !strongUnlocking(runState)) { | 303 | if (unlocking(runState) && (!strongUnlocking(runState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_041 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_045 | |||
|---|---|---|---|---|
|
315 lines 12633 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12642 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:49.537 | 1 | //Time : 2012-04-24 19:02:58.676 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState runState=map.get("handleMessage"); | 302 | SingleLockState handleState=map.get("handleMessage"); | |
| 303 | if (unlocking(runState) && (!strongUnlocking(runState))) { | 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_045 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_046 | |||
|---|---|---|---|---|
|
315 lines 12642 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12652 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:58.676 | 1 | //Time : 2012-04-24 19:03:04.851 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState handleState=map.get("handleMessage"); | 302 | SingleLockState handleState=map.get("handleMessage"); | |
| 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ handleMessage"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_046 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_047 | |||
|---|---|---|---|---|
|
315 lines 12652 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12656 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:03:04.851 | 1 | //Time : 2012-04-24 19:03:06.680 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState handleState=map.get("handleMessage"); | 302 | SingleLockState handleState=map.get("handleMessage"); | |
| 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Locking @ handleMessage"); | 304 | logNote("WEAK BUG: " + component.toString() + "Not Locking @ handleMessage"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_047 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_048 | |||
|---|---|---|---|---|
|
315 lines 12656 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12660 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:03:06.680 | 1 | //Time : 2012-04-24 19:03:08.478 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState handleState=map.get("handleMessage"); | 302 | SingleLockState handleState=map.get("handleMessage"); | |
| 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Not Locking @ handleMessage"); | 304 | logNote("WEAK BUG: " + component.toString() + "Not fullLocking @ handleMessage"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_048 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_049 | |||
|---|---|---|---|---|
|
315 lines 12660 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12662 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:03:08.478 | 1 | //Time : 2012-04-24 19:03:10.259 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState handleState=map.get("handleMessage"); | 302 | SingleLockState handleState=map.get("handleMessage"); | |
| 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Not fullLocking @ handleMessage"); | 304 | logNote("WEAK BUG: " + component.toString() + "Not full unocking @ handleMessage"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_049 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_050 | |||
|---|---|---|---|---|
|
315 lines 12662 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12663 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:03:10.259 | 1 | //Time : 2012-04-24 19:03:11.564 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState handleState=map.get("handleMessage"); | 302 | SingleLockState handleState=map.get("handleMessage"); | |
| 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Not full unocking @ handleMessage"); | 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_050 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_051 | |||
|---|---|---|---|---|
|
315 lines 12663 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12667 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:03:11.564 | 1 | //Time : 2012-04-24 19:07:41.313 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (weaklocking(onResumeState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState handleState=map.get("handleMessage"); | 302 | SingleLockState handleState=map.get("handleMessage"); | |
| 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_051 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_052 | |||
|---|---|---|---|---|
|
315 lines 12667 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12666 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:07:41.313 | 1 | //Time : 2012-04-24 19:07:44.650 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (weaklocking(onResumeState) && (!unlocking(onPauseState))) { | 281 | if (weaklocking(onPasueState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState handleState=map.get("handleMessage"); | 302 | SingleLockState handleState=map.get("handleMessage"); | |
| 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_052 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_053 | |||
|---|---|---|---|---|
|
315 lines 12666 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12666 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:07:44.650 | 1 | //Time : 2012-04-24 19:07:46.935 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (weaklocking(onPasueState) && (!unlocking(onPauseState))) { | 281 | if (weaklocking(onPauseState) && (!unlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState handleState=map.get("handleMessage"); | 302 | SingleLockState handleState=map.get("handleMessage"); | |
| 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_053 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_054 | |||
|---|---|---|---|---|
|
315 lines 12666 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12672 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:07:46.935 | 1 | //Time : 2012-04-24 19:07:52.334 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (weaklocking(onPauseState) && (!unlocking(onPauseState))) { | 281 | if (weaklocking(onPauseState) && (!strongunlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState handleState=map.get("handleMessage"); | 302 | SingleLockState handleState=map.get("handleMessage"); | |
| 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_054 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_056 | |||
|---|---|---|---|---|
|
315 lines 12672 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12672 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:07:52.334 | 1 | //Time : 2012-04-24 19:07:57.191 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (weaklocking(onPauseState) && (!strongunlocking(onPauseState))) { | 281 | if (weaklocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState handleState=map.get("handleMessage"); | 302 | SingleLockState handleState=map.get("handleMessage"); | |
| 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_056 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_057 | |||
|---|---|---|---|---|
|
315 lines 12672 bytes Last modified : Mon May 14 20:27:49 2012 |
315 lines 12674 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:07:57.191 | 1 | //Time : 2012-04-24 19:08:01.483 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (weaklocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 281 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 285 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 286 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 287 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 291 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 295 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 296 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 297 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 299 | } | |
| 300 | } | 300 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 301 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState handleState=map.get("handleMessage"); | 302 | SingleLockState handleState=map.get("handleMessage"); | |
| 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 308 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 309 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_057 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_058 | |||
|---|---|---|---|---|
|
315 lines 12674 bytes Last modified : Mon May 14 20:27:49 2012 |
318 lines 12847 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:08:01.483 | 1 | //Time : 2012-04-24 19:08:30.329 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 281 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |||
| 285 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |||
| 286 | } | |||
| 284 | } | 287 | } | |
| 285 | if (component.getComponentType().equals("Service")) { | 288 | if (component.getComponentType().equals("Service")) { | |
| 286 | SingleLockState onStartState=getServiceOnStart(); | 289 | SingleLockState onStartState=getServiceOnStart(); | |
| 287 | SingleLockState onDestroyState=map.get("onDestroy"); | 290 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 288 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 289 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 290 | } | 293 | } | |
| 291 | if (weakUnlocking(onDestroyState)) { | 294 | if (weakUnlocking(onDestroyState)) { | |
| 292 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 293 | } | 296 | } | |
| 294 | } | 297 | } | |
| 295 | if (component.getComponentType().equals("RunnableThread")) { | 298 | if (component.getComponentType().equals("RunnableThread")) { | |
| 296 | SingleLockState runState=map.get("run"); | 299 | SingleLockState runState=map.get("run"); | |
| 297 | if (locking(runState)) { | 300 | if (locking(runState)) { | |
| 298 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 299 | } | 302 | } | |
| 300 | } | 303 | } | |
| 301 | if (component.getComponentType().equals("Handler")) { | 304 | if (component.getComponentType().equals("Handler")) { | |
| 302 | SingleLockState handleState=map.get("handleMessage"); | 305 | SingleLockState handleState=map.get("handleMessage"); | |
| 303 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 305 | } | 308 | } | |
| 306 | } | 309 | } | |
| 307 | if (component.getComponentType().equals("BroadcastReceiver")) { | 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 308 | SingleLockState onReceiveState=map.get("onReceive"); | 311 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 309 | if (locking(onReceiveState)) { | 312 | if (locking(onReceiveState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 311 | } | 314 | } | |
| 312 | } | 315 | } | |
| 313 | } | 316 | } | |
| 314 | } | 317 | } | |
| 315 | } | 318 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_058 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_059 | |||
|---|---|---|---|---|
|
318 lines 12847 bytes Last modified : Mon May 14 20:27:49 2012 |
318 lines 12845 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:08:30.329 | 1 | //Time : 2012-04-24 19:08:35.198 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 281 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 285 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | } | 287 | } | |
| 288 | if (component.getComponentType().equals("Service")) { | 288 | if (component.getComponentType().equals("Service")) { | |
| 289 | SingleLockState onStartState=getServiceOnStart(); | 289 | SingleLockState onStartState=getServiceOnStart(); | |
| 290 | SingleLockState onDestroyState=map.get("onDestroy"); | 290 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | if (weakUnlocking(onDestroyState)) { | 294 | if (weakUnlocking(onDestroyState)) { | |
| 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 296 | } | 296 | } | |
| 297 | } | 297 | } | |
| 298 | if (component.getComponentType().equals("RunnableThread")) { | 298 | if (component.getComponentType().equals("RunnableThread")) { | |
| 299 | SingleLockState runState=map.get("run"); | 299 | SingleLockState runState=map.get("run"); | |
| 300 | if (locking(runState)) { | 300 | if (locking(runState)) { | |
| 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | if (component.getComponentType().equals("Handler")) { | 304 | if (component.getComponentType().equals("Handler")) { | |
| 305 | SingleLockState handleState=map.get("handleMessage"); | 305 | SingleLockState handleState=map.get("handleMessage"); | |
| 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } | |
| 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 311 | SingleLockState onReceiveState=map.get("onReceive"); | 311 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 312 | if (locking(onReceiveState)) { | 312 | if (locking(onReceiveState)) { | |
| 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_059 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_060 | |||
|---|---|---|---|---|
|
318 lines 12845 bytes Last modified : Mon May 14 20:27:49 2012 |
318 lines 12841 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:08:35.198 | 1 | //Time : 2012-04-24 19:08:39.016 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 281 | if (unlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | } | 287 | } | |
| 288 | if (component.getComponentType().equals("Service")) { | 288 | if (component.getComponentType().equals("Service")) { | |
| 289 | SingleLockState onStartState=getServiceOnStart(); | 289 | SingleLockState onStartState=getServiceOnStart(); | |
| 290 | SingleLockState onDestroyState=map.get("onDestroy"); | 290 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | if (weakUnlocking(onDestroyState)) { | 294 | if (weakUnlocking(onDestroyState)) { | |
| 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 296 | } | 296 | } | |
| 297 | } | 297 | } | |
| 298 | if (component.getComponentType().equals("RunnableThread")) { | 298 | if (component.getComponentType().equals("RunnableThread")) { | |
| 299 | SingleLockState runState=map.get("run"); | 299 | SingleLockState runState=map.get("run"); | |
| 300 | if (locking(runState)) { | 300 | if (locking(runState)) { | |
| 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | if (component.getComponentType().equals("Handler")) { | 304 | if (component.getComponentType().equals("Handler")) { | |
| 305 | SingleLockState handleState=map.get("handleMessage"); | 305 | SingleLockState handleState=map.get("handleMessage"); | |
| 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } | |
| 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 311 | SingleLockState onReceiveState=map.get("onReceive"); | 311 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 312 | if (locking(onReceiveState)) { | 312 | if (locking(onReceiveState)) { | |
| 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_060 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_061 | |||
|---|---|---|---|---|
|
318 lines 12841 bytes Last modified : Mon May 14 20:27:49 2012 |
318 lines 12842 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:08:39.016 | 1 | //Time : 2012-04-24 19:08:45.830 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (unlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 281 | if (!unlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | } | 287 | } | |
| 288 | if (component.getComponentType().equals("Service")) { | 288 | if (component.getComponentType().equals("Service")) { | |
| 289 | SingleLockState onStartState=getServiceOnStart(); | 289 | SingleLockState onStartState=getServiceOnStart(); | |
| 290 | SingleLockState onDestroyState=map.get("onDestroy"); | 290 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | if (weakUnlocking(onDestroyState)) { | 294 | if (weakUnlocking(onDestroyState)) { | |
| 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 296 | } | 296 | } | |
| 297 | } | 297 | } | |
| 298 | if (component.getComponentType().equals("RunnableThread")) { | 298 | if (component.getComponentType().equals("RunnableThread")) { | |
| 299 | SingleLockState runState=map.get("run"); | 299 | SingleLockState runState=map.get("run"); | |
| 300 | if (locking(runState)) { | 300 | if (locking(runState)) { | |
| 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | if (component.getComponentType().equals("Handler")) { | 304 | if (component.getComponentType().equals("Handler")) { | |
| 305 | SingleLockState handleState=map.get("handleMessage"); | 305 | SingleLockState handleState=map.get("handleMessage"); | |
| 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } | |
| 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 311 | SingleLockState onReceiveState=map.get("onReceive"); | 311 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 312 | if (locking(onReceiveState)) { | 312 | if (locking(onReceiveState)) { | |
| 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_061 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_062 | |||
|---|---|---|---|---|
|
318 lines 12842 bytes Last modified : Mon May 14 20:27:49 2012 |
318 lines 12806 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:08:45.830 | 1 | //Time : 2012-04-24 19:08:51.193 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return false; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (!unlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 281 | if (!unlocking(onPauseState)) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | } | 287 | } | |
| 288 | if (component.getComponentType().equals("Service")) { | 288 | if (component.getComponentType().equals("Service")) { | |
| 289 | SingleLockState onStartState=getServiceOnStart(); | 289 | SingleLockState onStartState=getServiceOnStart(); | |
| 290 | SingleLockState onDestroyState=map.get("onDestroy"); | 290 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | if (weakUnlocking(onDestroyState)) { | 294 | if (weakUnlocking(onDestroyState)) { | |
| 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 296 | } | 296 | } | |
| 297 | } | 297 | } | |
| 298 | if (component.getComponentType().equals("RunnableThread")) { | 298 | if (component.getComponentType().equals("RunnableThread")) { | |
| 299 | SingleLockState runState=map.get("run"); | 299 | SingleLockState runState=map.get("run"); | |
| 300 | if (locking(runState)) { | 300 | if (locking(runState)) { | |
| 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | if (component.getComponentType().equals("Handler")) { | 304 | if (component.getComponentType().equals("Handler")) { | |
| 305 | SingleLockState handleState=map.get("handleMessage"); | 305 | SingleLockState handleState=map.get("handleMessage"); | |
| 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } | |
| 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 311 | SingleLockState onReceiveState=map.get("onReceive"); | 311 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 312 | if (locking(onReceiveState)) { | 312 | if (locking(onReceiveState)) { | |
| 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_062 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_063 | |||
|---|---|---|---|---|
|
318 lines 12806 bytes Last modified : Mon May 14 20:27:49 2012 |
318 lines 12805 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:08:51.193 | 1 | //Time : 2012-04-24 19:09:14.993 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return false; | 230 | return true; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return false; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (!unlocking(onPauseState)) { | 281 | if (!unlocking(onPauseState)) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | } | 287 | } | |
| 288 | if (component.getComponentType().equals("Service")) { | 288 | if (component.getComponentType().equals("Service")) { | |
| 289 | SingleLockState onStartState=getServiceOnStart(); | 289 | SingleLockState onStartState=getServiceOnStart(); | |
| 290 | SingleLockState onDestroyState=map.get("onDestroy"); | 290 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | if (weakUnlocking(onDestroyState)) { | 294 | if (weakUnlocking(onDestroyState)) { | |
| 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 296 | } | 296 | } | |
| 297 | } | 297 | } | |
| 298 | if (component.getComponentType().equals("RunnableThread")) { | 298 | if (component.getComponentType().equals("RunnableThread")) { | |
| 299 | SingleLockState runState=map.get("run"); | 299 | SingleLockState runState=map.get("run"); | |
| 300 | if (locking(runState)) { | 300 | if (locking(runState)) { | |
| 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | if (component.getComponentType().equals("Handler")) { | 304 | if (component.getComponentType().equals("Handler")) { | |
| 305 | SingleLockState handleState=map.get("handleMessage"); | 305 | SingleLockState handleState=map.get("handleMessage"); | |
| 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } | |
| 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 311 | SingleLockState onReceiveState=map.get("onReceive"); | 311 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 312 | if (locking(onReceiveState)) { | 312 | if (locking(onReceiveState)) { | |
| 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_063 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_064 | |||
|---|---|---|---|---|
|
318 lines 12805 bytes Last modified : Mon May 14 20:27:49 2012 |
318 lines 12804 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:09:14.993 | 1 | //Time : 2012-04-24 19:09:18.874 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return true; | 230 | return true; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return false; | 236 | return true; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (!unlocking(onPauseState)) { | 281 | if (!unlocking(onPauseState)) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | } | 287 | } | |
| 288 | if (component.getComponentType().equals("Service")) { | 288 | if (component.getComponentType().equals("Service")) { | |
| 289 | SingleLockState onStartState=getServiceOnStart(); | 289 | SingleLockState onStartState=getServiceOnStart(); | |
| 290 | SingleLockState onDestroyState=map.get("onDestroy"); | 290 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | if (weakUnlocking(onDestroyState)) { | 294 | if (weakUnlocking(onDestroyState)) { | |
| 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 296 | } | 296 | } | |
| 297 | } | 297 | } | |
| 298 | if (component.getComponentType().equals("RunnableThread")) { | 298 | if (component.getComponentType().equals("RunnableThread")) { | |
| 299 | SingleLockState runState=map.get("run"); | 299 | SingleLockState runState=map.get("run"); | |
| 300 | if (locking(runState)) { | 300 | if (locking(runState)) { | |
| 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | if (component.getComponentType().equals("Handler")) { | 304 | if (component.getComponentType().equals("Handler")) { | |
| 305 | SingleLockState handleState=map.get("handleMessage"); | 305 | SingleLockState handleState=map.get("handleMessage"); | |
| 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } | |
| 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 311 | SingleLockState onReceiveState=map.get("onReceive"); | 311 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 312 | if (locking(onReceiveState)) { | 312 | if (locking(onReceiveState)) { | |
| 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_064 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_065 | |||
|---|---|---|---|---|
|
318 lines 12804 bytes Last modified : Mon May 14 20:27:49 2012 |
318 lines 12793 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:09:18.874 | 1 | //Time : 2012-04-24 19:09:52.799 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return true; | 230 | return true; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return true; | 236 | return true; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (!unlocking(onPauseState)) { | 281 | if (!unlocking(onPauseState)) { | |
| 282 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | } | 287 | } | |
| 288 | if (component.getComponentType().equals("Service")) { | 288 | if (component.getComponentType().equals("Service")) { | |
| 289 | SingleLockState onStartState=getServiceOnStart(); | 289 | SingleLockState onStartState=getServiceOnStart(); | |
| 290 | SingleLockState onDestroyState=map.get("onDestroy"); | 290 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | if (weakUnlocking(onDestroyState)) { | 294 | if (weakUnlocking(onDestroyState)) { | |
| 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 296 | } | 296 | } | |
| 297 | } | 297 | } | |
| 298 | if (component.getComponentType().equals("RunnableThread")) { | 298 | if (component.getComponentType().equals("RunnableThread")) { | |
| 299 | SingleLockState runState=map.get("run"); | 299 | SingleLockState runState=map.get("run"); | |
| 300 | if (locking(runState)) { | 300 | if (locking(runState)) { | |
| 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | if (component.getComponentType().equals("Handler")) { | 304 | if (component.getComponentType().equals("Handler")) { | |
| 305 | SingleLockState handleState=map.get("handleMessage"); | 305 | SingleLockState handleState=map.get("handleMessage"); | |
| 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } | |
| 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 311 | SingleLockState onReceiveState=map.get("onReceive"); | 311 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 312 | if (locking(onReceiveState)) { | 312 | if (locking(onReceiveState)) { | |
| 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_065 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_066 | |||
|---|---|---|---|---|
|
318 lines 12793 bytes Last modified : Mon May 14 20:27:49 2012 |
318 lines 12782 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:09:52.799 | 1 | //Time : 2012-04-24 19:09:55.740 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return true; | 230 | return true; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return true; | 236 | return true; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 265 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 266 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 267 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 268 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 270 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 271 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 272 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 274 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 275 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 276 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 279 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 280 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (!unlocking(onPauseState)) { | 281 | if (!unlocking(onPauseState)) { | |
| 282 | logNote("STRONG BUG: onPause (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: onPause (" + component.toString() + ")"); | |
| 283 | } | 283 | } | |
| 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 285 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 285 | logNote("WEAK BUG: onPause (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | } | 287 | } | |
| 288 | if (component.getComponentType().equals("Service")) { | 288 | if (component.getComponentType().equals("Service")) { | |
| 289 | SingleLockState onStartState=getServiceOnStart(); | 289 | SingleLockState onStartState=getServiceOnStart(); | |
| 290 | SingleLockState onDestroyState=map.get("onDestroy"); | 290 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 293 | } | 293 | } | |
| 294 | if (weakUnlocking(onDestroyState)) { | 294 | if (weakUnlocking(onDestroyState)) { | |
| 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 296 | } | 296 | } | |
| 297 | } | 297 | } | |
| 298 | if (component.getComponentType().equals("RunnableThread")) { | 298 | if (component.getComponentType().equals("RunnableThread")) { | |
| 299 | SingleLockState runState=map.get("run"); | 299 | SingleLockState runState=map.get("run"); | |
| 300 | if (locking(runState)) { | 300 | if (locking(runState)) { | |
| 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 302 | } | 302 | } | |
| 303 | } | 303 | } | |
| 304 | if (component.getComponentType().equals("Handler")) { | 304 | if (component.getComponentType().equals("Handler")) { | |
| 305 | SingleLockState handleState=map.get("handleMessage"); | 305 | SingleLockState handleState=map.get("handleMessage"); | |
| 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } | |
| 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 311 | SingleLockState onReceiveState=map.get("onReceive"); | 311 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 312 | if (locking(onReceiveState)) { | 312 | if (locking(onReceiveState)) { | |
| 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_066 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_067 | |||
|---|---|---|---|---|
|
318 lines 12782 bytes Last modified : Mon May 14 20:27:49 2012 |
317 lines 12719 bytes Last modified : Mon May 14 20:27:49 2012 |
|||
| 1 | //Time : 2012-04-24 19:09:55.740 | 1 | //Time : 2012-04-24 19:43:38.605 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 18 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 20 | /** | 20 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 21 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 22 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 24 | public class ComponentSummary { | |
| 25 | private Component component; | 25 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 28 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 29 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 32 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 34 | return allExitStates; | |
| 35 | } | 35 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 37 | allExitStates.put(n,st); | |
| 38 | } | 38 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 40 | callBackExitStates.put(cb,st); | |
| 41 | } | 41 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 43 | return allExitStates.get(method); | |
| 44 | } | 44 | } | |
| 45 | public String toString(){ | 45 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 46 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 48 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 49 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 51 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 56 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 57 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 58 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 59 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 60 | String name=cb.getName(); | |
| 61 | ; | 61 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 63 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | } | 68 | } | |
| 69 | return null; | 69 | return null; | |
| 70 | } | 70 | } | |
| 71 | } | 71 | } | |
| 72 | public AnalysisResults(){ | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 74 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 76 | /** | |
| 77 | * Invoke this after the component has been analyzed | 77 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 78 | * @param component | |
| 79 | */ | 79 | */ | |
| 80 | public void createComponentSummary( Component component){ | 80 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 83 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 85 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 87 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 90 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 91 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 93 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 96 | } | 96 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 99 | } | 99 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 102 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 105 | } | 105 | } | |
| 106 | else { | 106 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 108 | } | |
| 109 | } | 109 | } | |
| 110 | else { | 110 | else { | |
| 111 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | public ArrayList<String> processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 115 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 121 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 123 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 124 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 126 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 128 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 130 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 133 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 139 | printMethod=true; | |
| 140 | } | 140 | } | |
| 141 | } | 141 | } | |
| 142 | if (printMethod) { | 142 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 144 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 148 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 149 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 152 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 154 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 155 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 156 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 157 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 158 | } | |
| 159 | else { | 159 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 161 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 162 | usageMap.put(lu,set); | |
| 163 | } | 163 | } | |
| 164 | policy.addFact(node,mergedLS); | 164 | policy.addFact(node,mergedLS); | |
| 165 | } | 165 | } | |
| 166 | } | 166 | } | |
| 167 | } | 167 | } | |
| 168 | } | 168 | } | |
| 169 | if (printComponent) { | 169 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 171 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 172 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | 175 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 176 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 177 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 179 | System.out.println(" " + s.toString()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 183 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 184 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 185 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 187 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 188 | System.out.println("\n"); | |
| 189 | } | 189 | } | |
| 190 | result=logger.getStringList(); | 190 | result=logger.getStringList(); | |
| 191 | } | 191 | } | |
| 192 | return result; | 192 | return result; | |
| 193 | } | 193 | } | |
| 194 | public class Logger extends ArrayList<String> { | 194 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 196 | public void output(){ | |
| 197 | for ( String s : this) { | 197 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 198 | System.out.println(" " + s); | |
| 199 | } | 199 | } | |
| 200 | } | 200 | } | |
| 201 | public ArrayList<String> getStringList(){ | 201 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 202 | return this; | |
| 203 | } | 203 | } | |
| 204 | public String toString(){ | 204 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 207 | result.append(s + "\n"); | |
| 208 | } | 208 | } | |
| 209 | return result.toString(); | 209 | return result.toString(); | |
| 210 | } | 210 | } | |
| 211 | } | 211 | } | |
| 212 | public class ComponentPolicy { | 212 | public class ComponentPolicy { | |
| 213 | private Component component; | 213 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 214 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 215 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 217 | logger=new Logger(); | |
| 218 | } | 218 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 219 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 221 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 222 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 223 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 225 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 226 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 227 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 229 | } | |
| 230 | return true; | 230 | return true; | |
| 231 | } | 231 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 232 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 233 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 235 | } | |
| 236 | return true; | 236 | return true; | |
| 237 | } | 237 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 238 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 239 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 241 | } | |
| 242 | return false; | 242 | return false; | |
| 243 | } | 243 | } | |
| 244 | private Logger logger; | 244 | private Logger logger; | |
| 245 | private void logNote( String s){ | 245 | private void logNote( String s){ | |
| 246 | logger.add(s); | 246 | logger.add(s); | |
| 247 | } | 247 | } | |
| 248 | public Logger getLogger(){ | 248 | public Logger getLogger(){ | |
| 249 | return logger; | 249 | return logger; | |
| 250 | } | 250 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 251 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 252 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 254 | if (onStartCommand == null) { | |
| 255 | return onStart; | 255 | return onStart; | |
| 256 | } | 256 | } | |
| 257 | else { | 257 | else { | |
| 258 | return onStartCommand; | 258 | return onStartCommand; | |
| 259 | } | 259 | } | |
| 260 | } | 260 | } | |
| 261 | /** | 261 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 262 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 263 | */ | |
| 264 | public void solveFacts(){ | 264 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | |||
| 266 | if (component.getComponentType().equals("Activity")) { | 265 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 266 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 267 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 268 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 270 | } | 269 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 270 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 271 | if (locking(onStartState)) { | |
| 273 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 272 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 274 | } | 273 | } | |
| 275 | SingleLockState onRestartState=map.get("onRestart"); | 274 | SingleLockState onRestartState=map.get("onRestart"); | |
| 276 | if (locking(onRestartState)) { | 275 | if (locking(onRestartState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 278 | } | 277 | } | |
| 279 | SingleLockState onPauseState=map.get("onPause"); | 278 | SingleLockState onPauseState=map.get("onPause"); | |
| 280 | SingleLockState onResumeState=map.get("onResume"); | 279 | SingleLockState onResumeState=map.get("onResume"); | |
| 281 | if (!unlocking(onPauseState)) { | 280 | if (!unlocking(onPauseState)) { | |
| 282 | logNote("STRONG BUG: onPause (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: onPause (" + component.toString() + ")"); | |
| 283 | } | 282 | } | |
| 284 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 283 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 285 | logNote("WEAK BUG: onPause (" + component.toString() + ")"); | 284 | logNote("WEAK BUG: onPause (" + component.toString() + ")"); | |
| 286 | } | 285 | } | |
| 287 | } | 286 | } | |
| 288 | if (component.getComponentType().equals("Service")) { | 287 | if (component.getComponentType().equals("Service")) { | |
| 289 | SingleLockState onStartState=getServiceOnStart(); | 288 | SingleLockState onStartState=getServiceOnStart(); | |
| 290 | SingleLockState onDestroyState=map.get("onDestroy"); | 289 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 291 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 290 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 292 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 291 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 293 | } | 292 | } | |
| 294 | if (weakUnlocking(onDestroyState)) { | 293 | if (weakUnlocking(onDestroyState)) { | |
| 295 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 294 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 296 | } | 295 | } | |
| 297 | } | 296 | } | |
| 298 | if (component.getComponentType().equals("RunnableThread")) { | 297 | if (component.getComponentType().equals("RunnableThread")) { | |
| 299 | SingleLockState runState=map.get("run"); | 298 | SingleLockState runState=map.get("run"); | |
| 300 | if (locking(runState)) { | 299 | if (locking(runState)) { | |
| 301 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 302 | } | 301 | } | |
| 303 | } | 302 | } | |
| 304 | if (component.getComponentType().equals("Handler")) { | 303 | if (component.getComponentType().equals("Handler")) { | |
| 305 | SingleLockState handleState=map.get("handleMessage"); | 304 | SingleLockState handleState=map.get("handleMessage"); | |
| 306 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 305 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 307 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 306 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 308 | } | 307 | } | |
| 309 | } | 308 | } | |
| 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | 309 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 311 | SingleLockState onReceiveState=map.get("onReceive"); | 310 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 312 | if (locking(onReceiveState)) { | 311 | if (locking(onReceiveState)) { | |
| 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 314 | } | 313 | } | |
| 315 | } | 314 | } | |
| 316 | } | 315 | } | |
| 317 | } | 316 | } | |
| 318 | } | 317 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_067 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_068 | |||
|---|---|---|---|---|
|
317 lines 12719 bytes Last modified : Mon May 14 20:27:49 2012 |
333 lines 13323 bytes Last modified : Mon May 14 20:27:54 2012 |
|||
| 1 | //Time : 2012-04-24 19:43:38.605 | 1 | //Time : 2012-04-26 18:50:13.586 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | |||
| 19 | public class AnalysisResults { | 18 | public class AnalysisResults { | |
| 20 | /** | 19 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 20 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 21 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 23 | public class ComponentSummary { | |
| 25 | private Component component; | 24 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 27 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 28 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 31 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 33 | return allExitStates; | |
| 35 | } | 34 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 36 | allExitStates.put(n,st); | |
| 38 | } | 37 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 39 | callBackExitStates.put(cb,st); | |
| 41 | } | 40 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 41 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 42 | return allExitStates.get(method); | |
| 44 | } | 43 | } | |
| 45 | public String toString(){ | 44 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 45 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 47 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 48 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 49 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 50 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 51 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 52 | } | |
| 54 | } | 53 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 55 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 56 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 57 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 58 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 59 | String name=cb.getName(); | |
| 61 | ; | 60 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 61 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 62 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 64 | } | |
| 66 | } | 65 | } | |
| 67 | } | 66 | } | |
| 68 | } | 67 | } | |
| 69 | return null; | 68 | return null; | |
| 70 | } | 69 | } | |
| 71 | } | 70 | } | |
| 72 | public AnalysisResults(){ | 71 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 73 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |||
| 76 | public static class Result { | |||
| 77 | private ResultType resultType; | |||
| 78 | private String message; | |||
| 79 | public ResultType getResultType(){ | |||
| 80 | return resultType; | |||
| 81 | } | |||
| 82 | public String getMessage(){ | |||
| 83 | return message; | |||
| 84 | } | |||
| 85 | public Result( ResultType rt, String msg){ | |||
| 86 | message=msg; | |||
| 87 | resultType=rt; | |||
| 88 | } | |||
| 89 | public String toString(){ | |||
| 90 | return (resultType.name() + " " + message); | |||
| 91 | } | |||
| 92 | } | |||
| 76 | /** | 93 | /** | |
| 77 | * Invoke this after the component has been analyzed | 94 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 95 | * @param component | |
| 79 | */ | 96 | */ | |
| 80 | public void createComponentSummary( Component component){ | 97 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 98 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 100 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 102 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 104 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 105 | } | |
| 89 | } | 106 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 107 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 108 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 109 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 110 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 112 | return LockUsage.LOCKING; | |
| 96 | } | 113 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 115 | return LockUsage.EMPTY; | |
| 99 | } | 116 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 118 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 119 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 120 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 121 | return LockUsage.UNLOCKING; | |
| 105 | } | 122 | } | |
| 106 | else { | 123 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 124 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 125 | } | |
| 109 | } | 126 | } | |
| 110 | else { | 127 | else { | |
| 111 | return LockUsage.EMPTY; | 128 | return LockUsage.EMPTY; | |
| 112 | } | 129 | } | |
| 113 | } | 130 | } | |
| 114 | public ArrayList<String> processResults(){ | 131 | public ArrayList<Result> processResults(){ | |
| 115 | ArrayList<String> result=null; | 132 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 116 | System.out.println("\n=========================================="); | 133 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 137 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 138 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 139 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 140 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 141 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 143 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 145 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 146 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 147 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 150 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 151 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 153 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 154 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 155 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 156 | printMethod=true; | |
| 140 | } | 157 | } | |
| 141 | } | 158 | } | |
| 142 | if (printMethod) { | 159 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 161 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 165 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 166 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 169 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 171 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 172 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 173 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 174 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 175 | } | |
| 159 | else { | 176 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 178 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 179 | usageMap.put(lu,set); | |
| 163 | } | 180 | } | |
| 164 | policy.addFact(node,mergedLS); | 181 | policy.addFact(node,mergedLS); | |
| 165 | } | 182 | } | |
| 166 | } | 183 | } | |
| 167 | } | 184 | } | |
| 168 | } | 185 | } | |
| 169 | if (printComponent) { | 186 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 187 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 188 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 189 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 190 | } | |
| 174 | } | 191 | } | |
| 175 | System.out.println("==========================================\n"); | 192 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 193 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 196 | System.out.println(" " + s.toString()); | |
| 180 | } | 197 | } | |
| 181 | } | 198 | } | |
| 182 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 200 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 201 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 202 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 203 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 204 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 205 | System.out.println("\n"); | |
| 189 | } | 206 | } | |
| 190 | result=logger.getStringList(); | 207 | result=logger.getStringList(); | |
| 191 | } | 208 | } | |
| 192 | return result; | 209 | return result; | |
| 193 | } | 210 | } | |
| 194 | public class Logger extends ArrayList<String> { | 211 | public class Logger extends ArrayList<Result> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 212 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 213 | public void output(){ | |
| 197 | for ( String s : this) { | 214 | for ( Result r : this) { | |
| 198 | System.out.println(" " + s); | 215 | System.out.println(" " + r.getResultType().toString()); | |
| 199 | } | 216 | } | |
| 200 | } | 217 | } | |
| 201 | public ArrayList<String> getStringList(){ | 218 | public ArrayList<Result> getStringList(){ | |
| 202 | return this; | 219 | return this; | |
| 203 | } | 220 | } | |
| 204 | public String toString(){ | 221 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 222 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 223 | for ( Result r : this) { | |
| 207 | result.append(s + "\n"); | 224 | result.append(r.toString() + "\n"); | |
| 208 | } | 225 | } | |
| 209 | return result.toString(); | 226 | return result.toString(); | |
| 210 | } | 227 | } | |
| 211 | } | 228 | } | |
| 212 | public class ComponentPolicy { | 229 | public class ComponentPolicy { | |
| 213 | private Component component; | 230 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 231 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 232 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 233 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 234 | logger=new Logger(); | |
| 218 | } | 235 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 236 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 237 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 238 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 239 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 240 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 241 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 242 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 243 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 244 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 246 | } | |
| 230 | return true; | 247 | return true; | |
| 231 | } | 248 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 249 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 250 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 252 | } | |
| 236 | return true; | 253 | return true; | |
| 237 | } | 254 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 255 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 256 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 258 | } | |
| 242 | return false; | 259 | return false; | |
| 243 | } | 260 | } | |
| 244 | private Logger logger; | 261 | private Logger logger; | |
| 245 | private void logNote( String s){ | 262 | private void logNote( Result result){ | |
| 246 | logger.add(s); | 263 | logger.add(result); | |
| 247 | } | 264 | } | |
| 248 | public Logger getLogger(){ | 265 | public Logger getLogger(){ | |
| 249 | return logger; | 266 | return logger; | |
| 250 | } | 267 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 268 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 269 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 271 | if (onStartCommand == null) { | |
| 255 | return onStart; | 272 | return onStart; | |
| 256 | } | 273 | } | |
| 257 | else { | 274 | else { | |
| 258 | return onStartCommand; | 275 | return onStartCommand; | |
| 259 | } | 276 | } | |
| 260 | } | 277 | } | |
| 261 | /** | 278 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 279 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 280 | */ | |
| 264 | public void solveFacts(){ | 281 | public void solveFacts(){ | |
| 265 | if (component.getComponentType().equals("Activity")) { | 282 | if (component.getComponentType().equals("Activity")) { | |
| 266 | SingleLockState onCreateState=map.get("onCreate"); | 283 | SingleLockState onCreateState=map.get("onCreate"); | |
| 267 | if (locking(onCreateState)) { | 284 | if (locking(onCreateState)) { | |
| 268 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 269 | } | 286 | } | |
| 270 | SingleLockState onStartState=map.get("onStart"); | 287 | SingleLockState onStartState=map.get("onStart"); | |
| 271 | if (locking(onStartState)) { | 288 | if (locking(onStartState)) { | |
| 272 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 273 | } | 290 | } | |
| 274 | SingleLockState onRestartState=map.get("onRestart"); | 291 | SingleLockState onRestartState=map.get("onRestart"); | |
| 275 | if (locking(onRestartState)) { | 292 | if (locking(onRestartState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 277 | } | 294 | } | |
| 278 | SingleLockState onPauseState=map.get("onPause"); | 295 | SingleLockState onPauseState=map.get("onPause"); | |
| 279 | SingleLockState onResumeState=map.get("onResume"); | |||
| 280 | if (!unlocking(onPauseState)) { | 296 | if (!unlocking(onPauseState)) { | |
| 281 | logNote("STRONG BUG: onPause (" + component.toString() + ")"); | 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 282 | } | 298 | } | |
| 283 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 284 | logNote("WEAK BUG: onPause (" + component.toString() + ")"); | 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 285 | } | 301 | } | |
| 286 | } | 302 | } | |
| 287 | if (component.getComponentType().equals("Service")) { | 303 | if (component.getComponentType().equals("Service")) { | |
| 288 | SingleLockState onStartState=getServiceOnStart(); | 304 | SingleLockState onStartState=getServiceOnStart(); | |
| 289 | SingleLockState onDestroyState=map.get("onDestroy"); | 305 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 290 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 291 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 292 | } | 308 | } | |
| 293 | if (weakUnlocking(onDestroyState)) { | 309 | if (weakUnlocking(onDestroyState)) { | |
| 294 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 295 | } | 311 | } | |
| 296 | } | 312 | } | |
| 297 | if (component.getComponentType().equals("RunnableThread")) { | 313 | if (component.getComponentType().equals("RunnableThread")) { | |
| 298 | SingleLockState runState=map.get("run"); | 314 | SingleLockState runState=map.get("run"); | |
| 299 | if (locking(runState)) { | 315 | if (locking(runState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 301 | } | 317 | } | |
| 302 | } | 318 | } | |
| 303 | if (component.getComponentType().equals("Handler")) { | 319 | if (component.getComponentType().equals("Handler")) { | |
| 304 | SingleLockState handleState=map.get("handleMessage"); | 320 | SingleLockState handleState=map.get("handleMessage"); | |
| 305 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 307 | } | 323 | } | |
| 308 | } | 324 | } | |
| 309 | if (component.getComponentType().equals("BroadcastReceiver")) { | 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 310 | SingleLockState onReceiveState=map.get("onReceive"); | 326 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 311 | if (locking(onReceiveState)) { | 327 | if (locking(onReceiveState)) { | |
| 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 313 | } | 329 | } | |
| 314 | } | 330 | } | |
| 315 | } | 331 | } | |
| 316 | } | 332 | } | |
| 317 | } | 333 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_068 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_069 | |||
|---|---|---|---|---|
|
333 lines 13323 bytes Last modified : Mon May 14 20:27:54 2012 |
333 lines 13373 bytes Last modified : Mon May 14 20:27:55 2012 |
|||
| 1 | //Time : 2012-04-26 18:50:13.586 | 1 | //Time : 2012-04-26 20:48:57.245 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | public class AnalysisResults { | 18 | public class AnalysisResults { | |
| 19 | /** | 19 | /** | |
| 20 | * Main structures that hold the analysis results for every component | 20 | * Main structures that hold the analysis results for every component | |
| 21 | */ | 21 | */ | |
| 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 23 | public class ComponentSummary { | 23 | public class ComponentSummary { | |
| 24 | private Component component; | 24 | private Component component; | |
| 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 27 | public ComponentSummary( Component c){ | 27 | public ComponentSummary( Component c){ | |
| 28 | this.component=c; | 28 | this.component=c; | |
| 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 31 | } | 31 | } | |
| 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 33 | return allExitStates; | 33 | return allExitStates; | |
| 34 | } | 34 | } | |
| 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 36 | allExitStates.put(n,st); | 36 | allExitStates.put(n,st); | |
| 37 | } | 37 | } | |
| 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 39 | callBackExitStates.put(cb,st); | 39 | callBackExitStates.put(cb,st); | |
| 40 | } | 40 | } | |
| 41 | public CompoundLockState getStateForMethod( String method){ | 41 | public CompoundLockState getStateForMethod( String method){ | |
| 42 | return allExitStates.get(method); | 42 | return allExitStates.get(method); | |
| 43 | } | 43 | } | |
| 44 | public String toString(){ | 44 | public String toString(){ | |
| 45 | StringBuffer sb=new StringBuffer(); | 45 | StringBuffer sb=new StringBuffer(); | |
| 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 47 | CGNode next=it.next(); | 47 | CGNode next=it.next(); | |
| 48 | String name=next.getMethod().getName().toString(); | 48 | String name=next.getMethod().getName().toString(); | |
| 49 | CompoundLockState stateForMethod=getStateForMethod(name); | 49 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 50 | if (stateForMethod != null) { | 50 | if (stateForMethod != null) { | |
| 51 | sb.append(name + ":\n" + stateForMethod.toString()); | 51 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 52 | } | 52 | } | |
| 53 | } | 53 | } | |
| 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 55 | if (callbacks != null) { | 55 | if (callbacks != null) { | |
| 56 | if (callbacks.size() > 0) { | 56 | if (callbacks.size() > 0) { | |
| 57 | sb.append("Callbacks:\n"); | 57 | sb.append("Callbacks:\n"); | |
| 58 | for ( CallBack cb : callbacks) { | 58 | for ( CallBack cb : callbacks) { | |
| 59 | String name=cb.getName(); | 59 | String name=cb.getName(); | |
| 60 | ; | 60 | ; | |
| 61 | CompoundLockState stateForMethod=getStateForMethod(name); | 61 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 62 | if (stateForMethod != null) { | 62 | if (stateForMethod != null) { | |
| 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 64 | } | 64 | } | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | return null; | 68 | return null; | |
| 69 | } | 69 | } | |
| 70 | } | 70 | } | |
| 71 | public AnalysisResults(){ | 71 | public AnalysisResults(){ | |
| 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 73 | } | 73 | } | |
| 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 76 | public static class Result { | 76 | public static class Result { | |
| 77 | private ResultType resultType; | 77 | private ResultType resultType; | |
| 78 | private String message; | 78 | private String message; | |
| 79 | public ResultType getResultType(){ | 79 | public ResultType getResultType(){ | |
| 80 | return resultType; | 80 | return resultType; | |
| 81 | } | 81 | } | |
| 82 | public String getMessage(){ | 82 | public String getMessage(){ | |
| 83 | return message; | 83 | return message; | |
| 84 | } | 84 | } | |
| 85 | public Result( ResultType rt, String msg){ | 85 | public Result( ResultType rt, String msg){ | |
| 86 | message=msg; | 86 | message=msg; | |
| 87 | resultType=rt; | 87 | resultType=rt; | |
| 88 | } | 88 | } | |
| 89 | public String toString(){ | 89 | public String toString(){ | |
| 90 | return (resultType.name() + " " + message); | 90 | return (resultType.name() + " " + message); | |
| 91 | } | 91 | } | |
| 92 | } | 92 | } | |
| 93 | /** | 93 | /** | |
| 94 | * Invoke this after the component has been analyzed | 94 | * Invoke this after the component has been analyzed | |
| 95 | * @param component | 95 | * @param component | |
| 96 | */ | 96 | */ | |
| 97 | public void createComponentSummary( Component component){ | 97 | public void createComponentSummary( Component component){ | |
| 98 | ComponentSummary componentSummary=new ComponentSummary(component); | 98 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 100 | CGNode next=it.next(); | 100 | CGNode next=it.next(); | |
| 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 102 | if (exitState != null) { | 102 | if (exitState != null) { | |
| 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 104 | componentSummary.registerNodeState(next,compoundLockState); | 104 | componentSummary.registerNodeState(next,compoundLockState); | |
| 105 | } | 105 | } | |
| 106 | } | 106 | } | |
| 107 | allStates.add(Pair.make(component,componentSummary)); | 107 | allStates.add(Pair.make(component,componentSummary)); | |
| 108 | } | 108 | } | |
| 109 | private LockUsage getLockUsage( SingleLockState runState){ | 109 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 110 | if (runState != null) { | 110 | if (runState != null) { | |
| 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 112 | return LockUsage.LOCKING; | 112 | return LockUsage.LOCKING; | |
| 113 | } | 113 | } | |
| 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 115 | return LockUsage.EMPTY; | 115 | return LockUsage.EMPTY; | |
| 116 | } | 116 | } | |
| 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 118 | return LockUsage.FULL_UNLOCKING; | 118 | return LockUsage.FULL_UNLOCKING; | |
| 119 | } | 119 | } | |
| 120 | else if (runState.isMaybeReleased()) { | 120 | else if (runState.isMaybeReleased()) { | |
| 121 | return LockUsage.UNLOCKING; | 121 | return LockUsage.UNLOCKING; | |
| 122 | } | 122 | } | |
| 123 | else { | 123 | else { | |
| 124 | return LockUsage.UNKNOWN_STATE; | 124 | return LockUsage.UNKNOWN_STATE; | |
| 125 | } | 125 | } | |
| 126 | } | 126 | } | |
| 127 | else { | 127 | else { | |
| 128 | return LockUsage.EMPTY; | 128 | return LockUsage.EMPTY; | |
| 129 | } | 129 | } | |
| 130 | } | 130 | } | |
| 131 | public ArrayList<Result> processResults(){ | 131 | public ArrayList<Result> processResults(){ | |
| 132 | ArrayList<Result> result=new ArrayList<Result>(); | 132 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 133 | System.out.println("\n=========================================="); | 133 | System.out.println("\n=========================================="); | |
| 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 137 | Component component=pair.fst; | 137 | Component component=pair.fst; | |
| 138 | ComponentSummary cSummary=pair.snd; | 138 | ComponentSummary cSummary=pair.snd; | |
| 139 | ComponentPolicy policy=new ComponentPolicy(component); | 139 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 140 | StringBuffer sb=new StringBuffer(); | 140 | StringBuffer sb=new StringBuffer(); | |
| 141 | boolean printComponent=false; | 141 | boolean printComponent=false; | |
| 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 143 | CGNode node=e.getKey(); | 143 | CGNode node=e.getKey(); | |
| 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 145 | boolean printMethod=false; | 145 | boolean printMethod=false; | |
| 146 | LockUsage lockUsage=LockUsage.EMPTY; | 146 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 147 | CompoundLockState compLS=e.getValue(); | 147 | CompoundLockState compLS=e.getValue(); | |
| 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 150 | WakeLockInstance wli=fs.getKey(); | 150 | WakeLockInstance wli=fs.getKey(); | |
| 151 | Set<SingleLockState> sls=fs.getValue(); | 151 | Set<SingleLockState> sls=fs.getValue(); | |
| 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 153 | lockUsage=getLockUsage(sl); | 153 | lockUsage=getLockUsage(sl); | |
| 154 | lockUsages.put(wli,lockUsage); | 154 | lockUsages.put(wli,lockUsage); | |
| 155 | if (lockUsage != LockUsage.EMPTY) { | 155 | if (lockUsage != LockUsage.EMPTY) { | |
| 156 | printMethod=true; | 156 | printMethod=true; | |
| 157 | } | 157 | } | |
| 158 | } | 158 | } | |
| 159 | if (printMethod) { | 159 | if (printMethod) { | |
| 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 161 | printComponent=true; | 161 | printComponent=true; | |
| 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 165 | WakeLockInstance key=fs.getKey(); | 165 | WakeLockInstance key=fs.getKey(); | |
| 166 | Set<SingleLockState> value=fs.getValue(); | 166 | Set<SingleLockState> value=fs.getValue(); | |
| 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 169 | } | 169 | } | |
| 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 171 | LockUsage lu=getLockUsage(mergedLS); | 171 | LockUsage lu=getLockUsage(mergedLS); | |
| 172 | if (component.isCallBack(node)) { | 172 | if (component.isCallBack(node)) { | |
| 173 | if (usageMap.containsKey(lu)) { | 173 | if (usageMap.containsKey(lu)) { | |
| 174 | usageMap.get(lu).add(Pair.make(component,node)); | 174 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 175 | } | 175 | } | |
| 176 | else { | 176 | else { | |
| 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 178 | set.add(Pair.make(component,node)); | 178 | set.add(Pair.make(component,node)); | |
| 179 | usageMap.put(lu,set); | 179 | usageMap.put(lu,set); | |
| 180 | } | 180 | } | |
| 181 | policy.addFact(node,mergedLS); | 181 | policy.addFact(node,mergedLS); | |
| 182 | } | 182 | } | |
| 183 | } | 183 | } | |
| 184 | } | 184 | } | |
| 185 | } | 185 | } | |
| 186 | if (printComponent) { | 186 | if (printComponent) { | |
| 187 | System.out.println(component.toString() + "\n" + sb.toString()); | 187 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 188 | policy.solveFacts(); | 188 | policy.solveFacts(); | |
| 189 | componentMap.put(component,policy.getLogger()); | 189 | componentMap.put(component,policy.getLogger()); | |
| 190 | } | 190 | } | |
| 191 | } | 191 | } | |
| 192 | System.out.println("==========================================\n"); | 192 | System.out.println("==========================================\n"); | |
| 193 | for ( LockUsage e : usageMap.keySet()) { | 193 | for ( LockUsage e : usageMap.keySet()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 196 | System.out.println(" " + s.toString()); | 196 | System.out.println(" " + s.toString()); | |
| 197 | } | 197 | } | |
| 198 | } | 198 | } | |
| 199 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 200 | for ( Component e : componentMap.keySet()) { | 200 | for ( Component e : componentMap.keySet()) { | |
| 201 | Logger logger=componentMap.get(e); | 201 | Logger logger=componentMap.get(e); | |
| 202 | if (!logger.isEmpty()) { | 202 | if (!logger.isEmpty()) { | |
| 203 | System.out.println(e.toString()); | 203 | System.out.println(e.toString()); | |
| 204 | System.out.println(logger.toString()); | 204 | System.out.println(logger.toString()); | |
| 205 | System.out.println("\n"); | 205 | System.out.println("\n"); | |
| 206 | } | 206 | } | |
| 207 | result=logger.getStringList(); | 207 | result=logger.getStringList(); | |
| 208 | } | 208 | } | |
| 209 | return result; | 209 | return result; | |
| 210 | } | 210 | } | |
| 211 | public class Logger extends ArrayList<Result> { | 211 | public class Logger extends ArrayList<Result> { | |
| 212 | private static final long serialVersionUID=4402714524487791090L; | 212 | private static final long serialVersionUID=4402714524487791090L; | |
| 213 | public void output(){ | 213 | public void output(){ | |
| 214 | for ( Result r : this) { | 214 | for ( Result r : this) { | |
| 215 | System.out.println(" " + r.getResultType().toString()); | 215 | System.out.println(" " + r.getResultType().toString()); | |
| 216 | } | 216 | } | |
| 217 | } | 217 | } | |
| 218 | public ArrayList<Result> getStringList(){ | 218 | public ArrayList<Result> getStringList(){ | |
| 219 | return this; | 219 | return this; | |
| 220 | } | 220 | } | |
| 221 | public String toString(){ | 221 | public String toString(){ | |
| 222 | StringBuffer result=new StringBuffer(); | 222 | StringBuffer result=new StringBuffer(); | |
| 223 | for ( Result r : this) { | 223 | for ( Result r : this) { | |
| 224 | result.append(r.toString() + "\n"); | 224 | result.append(r.toString() + "\n"); | |
| 225 | } | 225 | } | |
| 226 | return result.toString(); | 226 | return result.toString(); | |
| 227 | } | 227 | } | |
| 228 | } | 228 | } | |
| 229 | public class ComponentPolicy { | 229 | public class ComponentPolicy { | |
| 230 | private Component component; | 230 | private Component component; | |
| 231 | public ComponentPolicy( Component component){ | 231 | public ComponentPolicy( Component component){ | |
| 232 | this.component=component; | 232 | this.component=component; | |
| 233 | map=new HashMap<String,SingleLockState>(); | 233 | map=new HashMap<String,SingleLockState>(); | |
| 234 | logger=new Logger(); | 234 | logger=new Logger(); | |
| 235 | } | 235 | } | |
| 236 | private HashMap<String,SingleLockState> map; | 236 | private HashMap<String,SingleLockState> map; | |
| 237 | public void addFact( CGNode n, SingleLockState st){ | 237 | public void addFact( CGNode n, SingleLockState st){ | |
| 238 | map.put(n.getMethod().getName().toString(),st); | 238 | map.put(n.getMethod().getName().toString(),st); | |
| 239 | } | 239 | } | |
| 240 | private boolean unlocking( SingleLockState state){ | 240 | private boolean unlocking( SingleLockState state){ | |
| 241 | return (strongUnlocking(state) || weakUnlocking(state)); | 241 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 242 | } | 242 | } | |
| 243 | private boolean strongUnlocking( SingleLockState state){ | 243 | private boolean strongUnlocking( SingleLockState state){ | |
| 244 | if (state != null) { | 244 | if (state != null) { | |
| 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 246 | } | 246 | } | |
| 247 | return true; | 247 | return true; | |
| 248 | } | 248 | } | |
| 249 | private boolean weakUnlocking( SingleLockState state){ | 249 | private boolean weakUnlocking( SingleLockState state){ | |
| 250 | if (state != null) { | 250 | if (state != null) { | |
| 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 252 | } | 252 | } | |
| 253 | return true; | 253 | return false; | |
| 254 | } | 254 | } | |
| 255 | private boolean locking( SingleLockState onCreateState){ | 255 | private boolean locking( SingleLockState onCreateState){ | |
| 256 | if (onCreateState != null) { | 256 | if (onCreateState != null) { | |
| 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 258 | } | 258 | } | |
| 259 | return false; | 259 | return false; | |
| 260 | } | 260 | } | |
| 261 | private Logger logger; | 261 | private Logger logger; | |
| 262 | private void logNote( Result result){ | 262 | private void logNote( Result result){ | |
| 263 | logger.add(result); | 263 | logger.add(result); | |
| 264 | } | 264 | } | |
| 265 | public Logger getLogger(){ | 265 | public Logger getLogger(){ | |
| 266 | return logger; | 266 | return logger; | |
| 267 | } | 267 | } | |
| 268 | private SingleLockState getServiceOnStart(){ | 268 | private SingleLockState getServiceOnStart(){ | |
| 269 | SingleLockState onStart=map.get("onStart"); | 269 | SingleLockState onStart=map.get("onStart"); | |
| 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 271 | if (onStartCommand == null) { | 271 | if (onStartCommand == null) { | |
| 272 | return onStart; | 272 | return onStart; | |
| 273 | } | 273 | } | |
| 274 | else { | 274 | else { | |
| 275 | return onStartCommand; | 275 | return onStartCommand; | |
| 276 | } | 276 | } | |
| 277 | } | 277 | } | |
| 278 | /** | 278 | /** | |
| 279 | * TODO: make sure the same lock is locked and unlocked... | 279 | * TODO: make sure the same lock is locked and unlocked... | |
| 280 | */ | 280 | */ | |
| 281 | public void solveFacts(){ | 281 | public void solveFacts(){ | |
| 282 | if (component.getComponentType().equals("Activity")) { | 282 | if (component.getComponentType().equals("Activity")) { | |
| 283 | SingleLockState onCreateState=map.get("onCreate"); | 283 | SingleLockState onCreateState=map.get("onCreate"); | |
| 284 | if (locking(onCreateState)) { | 284 | if (locking(onCreateState)) { | |
| 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onStartState=map.get("onStart"); | 287 | SingleLockState onStartState=map.get("onStart"); | |
| 288 | if (locking(onStartState)) { | 288 | if (locking(onStartState)) { | |
| 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 290 | } | 290 | } | |
| 291 | SingleLockState onRestartState=map.get("onRestart"); | 291 | SingleLockState onRestartState=map.get("onRestart"); | |
| 292 | if (locking(onRestartState)) { | 292 | if (locking(onRestartState)) { | |
| 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 294 | } | 294 | } | |
| 295 | SingleLockState onPauseState=map.get("onPause"); | 295 | SingleLockState onPauseState=map.get("onPause"); | |
| 296 | if (!unlocking(onPauseState)) { | 296 | if (!unlocking(onPauseState)) { | |
| 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("Service")) { | 303 | if (component.getComponentType().equals("Service")) { | |
| 304 | SingleLockState onStartState=getServiceOnStart(); | 304 | SingleLockState onStartState=getServiceOnStart(); | |
| 305 | SingleLockState onDestroyState=map.get("onDestroy"); | 305 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | if (weakUnlocking(onDestroyState)) { | 309 | if (weakUnlocking(onDestroyState)) { | |
| 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | if (component.getComponentType().equals("RunnableThread")) { | 313 | if (component.getComponentType().equals("RunnableThread")) { | |
| 314 | SingleLockState runState=map.get("run"); | 314 | SingleLockState runState=map.get("run"); | |
| 315 | if (locking(runState)) { | 315 | if (locking(runState)) { | |
| 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } | |
| 319 | if (component.getComponentType().equals("Handler")) { | 319 | if (component.getComponentType().equals("Handler")) { | |
| 320 | SingleLockState handleState=map.get("handleMessage"); | 320 | SingleLockState handleState=map.get("handleMessage"); | |
| 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 323 | } | 323 | } | |
| 324 | } | 324 | } | |
| 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 326 | SingleLockState onReceiveState=map.get("onReceive"); | 326 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 327 | if (locking(onReceiveState)) { | 327 | if (locking(onReceiveState)) { | |
| 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 329 | } | 329 | } | |
| 330 | } | 330 | } | |
| 331 | } | 331 | } | |
| 332 | } | 332 | } | |
| 333 | } | 333 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_069 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_070 | |||
|---|---|---|---|---|
|
333 lines 13373 bytes Last modified : Mon May 14 20:27:55 2012 |
333 lines 13372 bytes Last modified : Mon May 14 20:27:55 2012 |
|||
| 1 | //Time : 2012-04-26 20:48:57.245 | 1 | //Time : 2012-04-26 20:49:20.139 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | public class AnalysisResults { | 18 | public class AnalysisResults { | |
| 19 | /** | 19 | /** | |
| 20 | * Main structures that hold the analysis results for every component | 20 | * Main structures that hold the analysis results for every component | |
| 21 | */ | 21 | */ | |
| 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 23 | public class ComponentSummary { | 23 | public class ComponentSummary { | |
| 24 | private Component component; | 24 | private Component component; | |
| 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 27 | public ComponentSummary( Component c){ | 27 | public ComponentSummary( Component c){ | |
| 28 | this.component=c; | 28 | this.component=c; | |
| 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 31 | } | 31 | } | |
| 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 33 | return allExitStates; | 33 | return allExitStates; | |
| 34 | } | 34 | } | |
| 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 36 | allExitStates.put(n,st); | 36 | allExitStates.put(n,st); | |
| 37 | } | 37 | } | |
| 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 39 | callBackExitStates.put(cb,st); | 39 | callBackExitStates.put(cb,st); | |
| 40 | } | 40 | } | |
| 41 | public CompoundLockState getStateForMethod( String method){ | 41 | public CompoundLockState getStateForMethod( String method){ | |
| 42 | return allExitStates.get(method); | 42 | return allExitStates.get(method); | |
| 43 | } | 43 | } | |
| 44 | public String toString(){ | 44 | public String toString(){ | |
| 45 | StringBuffer sb=new StringBuffer(); | 45 | StringBuffer sb=new StringBuffer(); | |
| 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 47 | CGNode next=it.next(); | 47 | CGNode next=it.next(); | |
| 48 | String name=next.getMethod().getName().toString(); | 48 | String name=next.getMethod().getName().toString(); | |
| 49 | CompoundLockState stateForMethod=getStateForMethod(name); | 49 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 50 | if (stateForMethod != null) { | 50 | if (stateForMethod != null) { | |
| 51 | sb.append(name + ":\n" + stateForMethod.toString()); | 51 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 52 | } | 52 | } | |
| 53 | } | 53 | } | |
| 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 55 | if (callbacks != null) { | 55 | if (callbacks != null) { | |
| 56 | if (callbacks.size() > 0) { | 56 | if (callbacks.size() > 0) { | |
| 57 | sb.append("Callbacks:\n"); | 57 | sb.append("Callbacks:\n"); | |
| 58 | for ( CallBack cb : callbacks) { | 58 | for ( CallBack cb : callbacks) { | |
| 59 | String name=cb.getName(); | 59 | String name=cb.getName(); | |
| 60 | ; | 60 | ; | |
| 61 | CompoundLockState stateForMethod=getStateForMethod(name); | 61 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 62 | if (stateForMethod != null) { | 62 | if (stateForMethod != null) { | |
| 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 64 | } | 64 | } | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | return null; | 68 | return null; | |
| 69 | } | 69 | } | |
| 70 | } | 70 | } | |
| 71 | public AnalysisResults(){ | 71 | public AnalysisResults(){ | |
| 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 73 | } | 73 | } | |
| 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 76 | public static class Result { | 76 | public static class Result { | |
| 77 | private ResultType resultType; | 77 | private ResultType resultType; | |
| 78 | private String message; | 78 | private String message; | |
| 79 | public ResultType getResultType(){ | 79 | public ResultType getResultType(){ | |
| 80 | return resultType; | 80 | return resultType; | |
| 81 | } | 81 | } | |
| 82 | public String getMessage(){ | 82 | public String getMessage(){ | |
| 83 | return message; | 83 | return message; | |
| 84 | } | 84 | } | |
| 85 | public Result( ResultType rt, String msg){ | 85 | public Result( ResultType rt, String msg){ | |
| 86 | message=msg; | 86 | message=msg; | |
| 87 | resultType=rt; | 87 | resultType=rt; | |
| 88 | } | 88 | } | |
| 89 | public String toString(){ | 89 | public String toString(){ | |
| 90 | return (resultType.name() + " " + message); | 90 | return (resultType.name() + " " + message); | |
| 91 | } | 91 | } | |
| 92 | } | 92 | } | |
| 93 | /** | 93 | /** | |
| 94 | * Invoke this after the component has been analyzed | 94 | * Invoke this after the component has been analyzed | |
| 95 | * @param component | 95 | * @param component | |
| 96 | */ | 96 | */ | |
| 97 | public void createComponentSummary( Component component){ | 97 | public void createComponentSummary( Component component){ | |
| 98 | ComponentSummary componentSummary=new ComponentSummary(component); | 98 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 100 | CGNode next=it.next(); | 100 | CGNode next=it.next(); | |
| 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 102 | if (exitState != null) { | 102 | if (exitState != null) { | |
| 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 104 | componentSummary.registerNodeState(next,compoundLockState); | 104 | componentSummary.registerNodeState(next,compoundLockState); | |
| 105 | } | 105 | } | |
| 106 | } | 106 | } | |
| 107 | allStates.add(Pair.make(component,componentSummary)); | 107 | allStates.add(Pair.make(component,componentSummary)); | |
| 108 | } | 108 | } | |
| 109 | private LockUsage getLockUsage( SingleLockState runState){ | 109 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 110 | if (runState != null) { | 110 | if (runState != null) { | |
| 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 112 | return LockUsage.LOCKING; | 112 | return LockUsage.LOCKING; | |
| 113 | } | 113 | } | |
| 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 115 | return LockUsage.EMPTY; | 115 | return LockUsage.EMPTY; | |
| 116 | } | 116 | } | |
| 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 118 | return LockUsage.FULL_UNLOCKING; | 118 | return LockUsage.FULL_UNLOCKING; | |
| 119 | } | 119 | } | |
| 120 | else if (runState.isMaybeReleased()) { | 120 | else if (runState.isMaybeReleased()) { | |
| 121 | return LockUsage.UNLOCKING; | 121 | return LockUsage.UNLOCKING; | |
| 122 | } | 122 | } | |
| 123 | else { | 123 | else { | |
| 124 | return LockUsage.UNKNOWN_STATE; | 124 | return LockUsage.UNKNOWN_STATE; | |
| 125 | } | 125 | } | |
| 126 | } | 126 | } | |
| 127 | else { | 127 | else { | |
| 128 | return LockUsage.EMPTY; | 128 | return LockUsage.EMPTY; | |
| 129 | } | 129 | } | |
| 130 | } | 130 | } | |
| 131 | public ArrayList<Result> processResults(){ | 131 | public ArrayList<Result> processResults(){ | |
| 132 | ArrayList<Result> result=new ArrayList<Result>(); | 132 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 133 | System.out.println("\n=========================================="); | 133 | System.out.println("\n=========================================="); | |
| 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 137 | Component component=pair.fst; | 137 | Component component=pair.fst; | |
| 138 | ComponentSummary cSummary=pair.snd; | 138 | ComponentSummary cSummary=pair.snd; | |
| 139 | ComponentPolicy policy=new ComponentPolicy(component); | 139 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 140 | StringBuffer sb=new StringBuffer(); | 140 | StringBuffer sb=new StringBuffer(); | |
| 141 | boolean printComponent=false; | 141 | boolean printComponent=false; | |
| 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 143 | CGNode node=e.getKey(); | 143 | CGNode node=e.getKey(); | |
| 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 145 | boolean printMethod=false; | 145 | boolean printMethod=false; | |
| 146 | LockUsage lockUsage=LockUsage.EMPTY; | 146 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 147 | CompoundLockState compLS=e.getValue(); | 147 | CompoundLockState compLS=e.getValue(); | |
| 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 150 | WakeLockInstance wli=fs.getKey(); | 150 | WakeLockInstance wli=fs.getKey(); | |
| 151 | Set<SingleLockState> sls=fs.getValue(); | 151 | Set<SingleLockState> sls=fs.getValue(); | |
| 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 153 | lockUsage=getLockUsage(sl); | 153 | lockUsage=getLockUsage(sl); | |
| 154 | lockUsages.put(wli,lockUsage); | 154 | lockUsages.put(wli,lockUsage); | |
| 155 | if (lockUsage != LockUsage.EMPTY) { | 155 | if (lockUsage != LockUsage.EMPTY) { | |
| 156 | printMethod=true; | 156 | printMethod=true; | |
| 157 | } | 157 | } | |
| 158 | } | 158 | } | |
| 159 | if (printMethod) { | 159 | if (printMethod) { | |
| 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 161 | printComponent=true; | 161 | printComponent=true; | |
| 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 165 | WakeLockInstance key=fs.getKey(); | 165 | WakeLockInstance key=fs.getKey(); | |
| 166 | Set<SingleLockState> value=fs.getValue(); | 166 | Set<SingleLockState> value=fs.getValue(); | |
| 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 169 | } | 169 | } | |
| 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 171 | LockUsage lu=getLockUsage(mergedLS); | 171 | LockUsage lu=getLockUsage(mergedLS); | |
| 172 | if (component.isCallBack(node)) { | 172 | if (component.isCallBack(node)) { | |
| 173 | if (usageMap.containsKey(lu)) { | 173 | if (usageMap.containsKey(lu)) { | |
| 174 | usageMap.get(lu).add(Pair.make(component,node)); | 174 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 175 | } | 175 | } | |
| 176 | else { | 176 | else { | |
| 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 178 | set.add(Pair.make(component,node)); | 178 | set.add(Pair.make(component,node)); | |
| 179 | usageMap.put(lu,set); | 179 | usageMap.put(lu,set); | |
| 180 | } | 180 | } | |
| 181 | policy.addFact(node,mergedLS); | 181 | policy.addFact(node,mergedLS); | |
| 182 | } | 182 | } | |
| 183 | } | 183 | } | |
| 184 | } | 184 | } | |
| 185 | } | 185 | } | |
| 186 | if (printComponent) { | 186 | if (printComponent) { | |
| 187 | System.out.println(component.toString() + "\n" + sb.toString()); | 187 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 188 | policy.solveFacts(); | 188 | policy.solveFacts(); | |
| 189 | componentMap.put(component,policy.getLogger()); | 189 | componentMap.put(component,policy.getLogger()); | |
| 190 | } | 190 | } | |
| 191 | } | 191 | } | |
| 192 | System.out.println("==========================================\n"); | 192 | System.out.println("==========================================\n"); | |
| 193 | for ( LockUsage e : usageMap.keySet()) { | 193 | for ( LockUsage e : usageMap.keySet()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 196 | System.out.println(" " + s.toString()); | 196 | System.out.println(" " + s.toString()); | |
| 197 | } | 197 | } | |
| 198 | } | 198 | } | |
| 199 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 200 | for ( Component e : componentMap.keySet()) { | 200 | for ( Component e : componentMap.keySet()) { | |
| 201 | Logger logger=componentMap.get(e); | 201 | Logger logger=componentMap.get(e); | |
| 202 | if (!logger.isEmpty()) { | 202 | if (!logger.isEmpty()) { | |
| 203 | System.out.println(e.toString()); | 203 | System.out.println(e.toString()); | |
| 204 | System.out.println(logger.toString()); | 204 | System.out.println(logger.toString()); | |
| 205 | System.out.println("\n"); | 205 | System.out.println("\n"); | |
| 206 | } | 206 | } | |
| 207 | result=logger.getStringList(); | 207 | result=logger.getStringList(); | |
| 208 | } | 208 | } | |
| 209 | return result; | 209 | return result; | |
| 210 | } | 210 | } | |
| 211 | public class Logger extends ArrayList<Result> { | 211 | public class Logger extends ArrayList<Result> { | |
| 212 | private static final long serialVersionUID=4402714524487791090L; | 212 | private static final long serialVersionUID=4402714524487791090L; | |
| 213 | public void output(){ | 213 | public void output(){ | |
| 214 | for ( Result r : this) { | 214 | for ( Result r : this) { | |
| 215 | System.out.println(" " + r.getResultType().toString()); | 215 | System.out.println(" " + r.getResultType().toString()); | |
| 216 | } | 216 | } | |
| 217 | } | 217 | } | |
| 218 | public ArrayList<Result> getStringList(){ | 218 | public ArrayList<Result> getStringList(){ | |
| 219 | return this; | 219 | return this; | |
| 220 | } | 220 | } | |
| 221 | public String toString(){ | 221 | public String toString(){ | |
| 222 | StringBuffer result=new StringBuffer(); | 222 | StringBuffer result=new StringBuffer(); | |
| 223 | for ( Result r : this) { | 223 | for ( Result r : this) { | |
| 224 | result.append(r.toString() + "\n"); | 224 | result.append(r.toString() + "\n"); | |
| 225 | } | 225 | } | |
| 226 | return result.toString(); | 226 | return result.toString(); | |
| 227 | } | 227 | } | |
| 228 | } | 228 | } | |
| 229 | public class ComponentPolicy { | 229 | public class ComponentPolicy { | |
| 230 | private Component component; | 230 | private Component component; | |
| 231 | public ComponentPolicy( Component component){ | 231 | public ComponentPolicy( Component component){ | |
| 232 | this.component=component; | 232 | this.component=component; | |
| 233 | map=new HashMap<String,SingleLockState>(); | 233 | map=new HashMap<String,SingleLockState>(); | |
| 234 | logger=new Logger(); | 234 | logger=new Logger(); | |
| 235 | } | 235 | } | |
| 236 | private HashMap<String,SingleLockState> map; | 236 | private HashMap<String,SingleLockState> map; | |
| 237 | public void addFact( CGNode n, SingleLockState st){ | 237 | public void addFact( CGNode n, SingleLockState st){ | |
| 238 | map.put(n.getMethod().getName().toString(),st); | 238 | map.put(n.getMethod().getName().toString(),st); | |
| 239 | } | 239 | } | |
| 240 | private boolean unlocking( SingleLockState state){ | 240 | private boolean unlocking( SingleLockState state){ | |
| 241 | return (strongUnlocking(state) || weakUnlocking(state)); | 241 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 242 | } | 242 | } | |
| 243 | private boolean strongUnlocking( SingleLockState state){ | 243 | private boolean strongUnlocking( SingleLockState state){ | |
| 244 | if (state != null) { | 244 | if (state != null) { | |
| 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 246 | } | 246 | } | |
| 247 | return true; | 247 | return true; | |
| 248 | } | 248 | } | |
| 249 | private boolean weakUnlocking( SingleLockState state){ | 249 | private boolean weakUnlocking( SingleLockState state){ | |
| 250 | if (state != null) { | 250 | if (state != null) { | |
| 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 252 | } | 252 | } | |
| 253 | return false; | 253 | return true; | |
| 254 | } | 254 | } | |
| 255 | private boolean locking( SingleLockState onCreateState){ | 255 | private boolean locking( SingleLockState onCreateState){ | |
| 256 | if (onCreateState != null) { | 256 | if (onCreateState != null) { | |
| 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 258 | } | 258 | } | |
| 259 | return false; | 259 | return false; | |
| 260 | } | 260 | } | |
| 261 | private Logger logger; | 261 | private Logger logger; | |
| 262 | private void logNote( Result result){ | 262 | private void logNote( Result result){ | |
| 263 | logger.add(result); | 263 | logger.add(result); | |
| 264 | } | 264 | } | |
| 265 | public Logger getLogger(){ | 265 | public Logger getLogger(){ | |
| 266 | return logger; | 266 | return logger; | |
| 267 | } | 267 | } | |
| 268 | private SingleLockState getServiceOnStart(){ | 268 | private SingleLockState getServiceOnStart(){ | |
| 269 | SingleLockState onStart=map.get("onStart"); | 269 | SingleLockState onStart=map.get("onStart"); | |
| 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 271 | if (onStartCommand == null) { | 271 | if (onStartCommand == null) { | |
| 272 | return onStart; | 272 | return onStart; | |
| 273 | } | 273 | } | |
| 274 | else { | 274 | else { | |
| 275 | return onStartCommand; | 275 | return onStartCommand; | |
| 276 | } | 276 | } | |
| 277 | } | 277 | } | |
| 278 | /** | 278 | /** | |
| 279 | * TODO: make sure the same lock is locked and unlocked... | 279 | * TODO: make sure the same lock is locked and unlocked... | |
| 280 | */ | 280 | */ | |
| 281 | public void solveFacts(){ | 281 | public void solveFacts(){ | |
| 282 | if (component.getComponentType().equals("Activity")) { | 282 | if (component.getComponentType().equals("Activity")) { | |
| 283 | SingleLockState onCreateState=map.get("onCreate"); | 283 | SingleLockState onCreateState=map.get("onCreate"); | |
| 284 | if (locking(onCreateState)) { | 284 | if (locking(onCreateState)) { | |
| 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onStartState=map.get("onStart"); | 287 | SingleLockState onStartState=map.get("onStart"); | |
| 288 | if (locking(onStartState)) { | 288 | if (locking(onStartState)) { | |
| 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 290 | } | 290 | } | |
| 291 | SingleLockState onRestartState=map.get("onRestart"); | 291 | SingleLockState onRestartState=map.get("onRestart"); | |
| 292 | if (locking(onRestartState)) { | 292 | if (locking(onRestartState)) { | |
| 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 294 | } | 294 | } | |
| 295 | SingleLockState onPauseState=map.get("onPause"); | 295 | SingleLockState onPauseState=map.get("onPause"); | |
| 296 | if (!unlocking(onPauseState)) { | 296 | if (!unlocking(onPauseState)) { | |
| 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("Service")) { | 303 | if (component.getComponentType().equals("Service")) { | |
| 304 | SingleLockState onStartState=getServiceOnStart(); | 304 | SingleLockState onStartState=getServiceOnStart(); | |
| 305 | SingleLockState onDestroyState=map.get("onDestroy"); | 305 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | if (weakUnlocking(onDestroyState)) { | 309 | if (weakUnlocking(onDestroyState)) { | |
| 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | if (component.getComponentType().equals("RunnableThread")) { | 313 | if (component.getComponentType().equals("RunnableThread")) { | |
| 314 | SingleLockState runState=map.get("run"); | 314 | SingleLockState runState=map.get("run"); | |
| 315 | if (locking(runState)) { | 315 | if (locking(runState)) { | |
| 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } | |
| 319 | if (component.getComponentType().equals("Handler")) { | 319 | if (component.getComponentType().equals("Handler")) { | |
| 320 | SingleLockState handleState=map.get("handleMessage"); | 320 | SingleLockState handleState=map.get("handleMessage"); | |
| 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 323 | } | 323 | } | |
| 324 | } | 324 | } | |
| 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 326 | SingleLockState onReceiveState=map.get("onReceive"); | 326 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 327 | if (locking(onReceiveState)) { | 327 | if (locking(onReceiveState)) { | |
| 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 329 | } | 329 | } | |
| 330 | } | 330 | } | |
| 331 | } | 331 | } | |
| 332 | } | 332 | } | |
| 333 | } | 333 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_070 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_072 | |||
|---|---|---|---|---|
|
333 lines 13372 bytes Last modified : Mon May 14 20:27:55 2012 |
333 lines 13380 bytes Last modified : Mon May 14 20:27:55 2012 |
|||
| 1 | //Time : 2012-04-26 20:49:20.139 | 1 | //Time : 2012-04-26 20:49:39.030 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | public class AnalysisResults { | 18 | public class AnalysisResults { | |
| 19 | /** | 19 | /** | |
| 20 | * Main structures that hold the analysis results for every component | 20 | * Main structures that hold the analysis results for every component | |
| 21 | */ | 21 | */ | |
| 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 23 | public class ComponentSummary { | 23 | public class ComponentSummary { | |
| 24 | private Component component; | 24 | private Component component; | |
| 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 27 | public ComponentSummary( Component c){ | 27 | public ComponentSummary( Component c){ | |
| 28 | this.component=c; | 28 | this.component=c; | |
| 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 31 | } | 31 | } | |
| 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 33 | return allExitStates; | 33 | return allExitStates; | |
| 34 | } | 34 | } | |
| 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 36 | allExitStates.put(n,st); | 36 | allExitStates.put(n,st); | |
| 37 | } | 37 | } | |
| 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 39 | callBackExitStates.put(cb,st); | 39 | callBackExitStates.put(cb,st); | |
| 40 | } | 40 | } | |
| 41 | public CompoundLockState getStateForMethod( String method){ | 41 | public CompoundLockState getStateForMethod( String method){ | |
| 42 | return allExitStates.get(method); | 42 | return allExitStates.get(method); | |
| 43 | } | 43 | } | |
| 44 | public String toString(){ | 44 | public String toString(){ | |
| 45 | StringBuffer sb=new StringBuffer(); | 45 | StringBuffer sb=new StringBuffer(); | |
| 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 47 | CGNode next=it.next(); | 47 | CGNode next=it.next(); | |
| 48 | String name=next.getMethod().getName().toString(); | 48 | String name=next.getMethod().getName().toString(); | |
| 49 | CompoundLockState stateForMethod=getStateForMethod(name); | 49 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 50 | if (stateForMethod != null) { | 50 | if (stateForMethod != null) { | |
| 51 | sb.append(name + ":\n" + stateForMethod.toString()); | 51 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 52 | } | 52 | } | |
| 53 | } | 53 | } | |
| 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 55 | if (callbacks != null) { | 55 | if (callbacks != null) { | |
| 56 | if (callbacks.size() > 0) { | 56 | if (callbacks.size() > 0) { | |
| 57 | sb.append("Callbacks:\n"); | 57 | sb.append("Callbacks:\n"); | |
| 58 | for ( CallBack cb : callbacks) { | 58 | for ( CallBack cb : callbacks) { | |
| 59 | String name=cb.getName(); | 59 | String name=cb.getName(); | |
| 60 | ; | 60 | ; | |
| 61 | CompoundLockState stateForMethod=getStateForMethod(name); | 61 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 62 | if (stateForMethod != null) { | 62 | if (stateForMethod != null) { | |
| 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 64 | } | 64 | } | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | return null; | 68 | return null; | |
| 69 | } | 69 | } | |
| 70 | } | 70 | } | |
| 71 | public AnalysisResults(){ | 71 | public AnalysisResults(){ | |
| 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 73 | } | 73 | } | |
| 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 76 | public static class Result { | 76 | public static class Result { | |
| 77 | private ResultType resultType; | 77 | private ResultType resultType; | |
| 78 | private String message; | 78 | private String message; | |
| 79 | public ResultType getResultType(){ | 79 | public ResultType getResultType(){ | |
| 80 | return resultType; | 80 | return resultType; | |
| 81 | } | 81 | } | |
| 82 | public String getMessage(){ | 82 | public String getMessage(){ | |
| 83 | return message; | 83 | return message; | |
| 84 | } | 84 | } | |
| 85 | public Result( ResultType rt, String msg){ | 85 | public Result( ResultType rt, String msg){ | |
| 86 | message=msg; | 86 | message=msg; | |
| 87 | resultType=rt; | 87 | resultType=rt; | |
| 88 | } | 88 | } | |
| 89 | public String toString(){ | 89 | public String toString(){ | |
| 90 | return (resultType.name() + " " + message); | 90 | return (resultType.name() + " " + message); | |
| 91 | } | 91 | } | |
| 92 | } | 92 | } | |
| 93 | /** | 93 | /** | |
| 94 | * Invoke this after the component has been analyzed | 94 | * Invoke this after the component has been analyzed | |
| 95 | * @param component | 95 | * @param component | |
| 96 | */ | 96 | */ | |
| 97 | public void createComponentSummary( Component component){ | 97 | public void createComponentSummary( Component component){ | |
| 98 | ComponentSummary componentSummary=new ComponentSummary(component); | 98 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 100 | CGNode next=it.next(); | 100 | CGNode next=it.next(); | |
| 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 102 | if (exitState != null) { | 102 | if (exitState != null) { | |
| 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 104 | componentSummary.registerNodeState(next,compoundLockState); | 104 | componentSummary.registerNodeState(next,compoundLockState); | |
| 105 | } | 105 | } | |
| 106 | } | 106 | } | |
| 107 | allStates.add(Pair.make(component,componentSummary)); | 107 | allStates.add(Pair.make(component,componentSummary)); | |
| 108 | } | 108 | } | |
| 109 | private LockUsage getLockUsage( SingleLockState runState){ | 109 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 110 | if (runState != null) { | 110 | if (runState != null) { | |
| 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 112 | return LockUsage.LOCKING; | 112 | return LockUsage.LOCKING; | |
| 113 | } | 113 | } | |
| 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 115 | return LockUsage.EMPTY; | 115 | return LockUsage.EMPTY; | |
| 116 | } | 116 | } | |
| 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 118 | return LockUsage.FULL_UNLOCKING; | 118 | return LockUsage.FULL_UNLOCKING; | |
| 119 | } | 119 | } | |
| 120 | else if (runState.isMaybeReleased()) { | 120 | else if (runState.isMaybeReleased()) { | |
| 121 | return LockUsage.UNLOCKING; | 121 | return LockUsage.UNLOCKING; | |
| 122 | } | 122 | } | |
| 123 | else { | 123 | else { | |
| 124 | return LockUsage.UNKNOWN_STATE; | 124 | return LockUsage.UNKNOWN_STATE; | |
| 125 | } | 125 | } | |
| 126 | } | 126 | } | |
| 127 | else { | 127 | else { | |
| 128 | return LockUsage.EMPTY; | 128 | return LockUsage.EMPTY; | |
| 129 | } | 129 | } | |
| 130 | } | 130 | } | |
| 131 | public ArrayList<Result> processResults(){ | 131 | public ArrayList<Result> processResults(){ | |
| 132 | ArrayList<Result> result=new ArrayList<Result>(); | 132 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 133 | System.out.println("\n=========================================="); | 133 | System.out.println("\n=========================================="); | |
| 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 137 | Component component=pair.fst; | 137 | Component component=pair.fst; | |
| 138 | ComponentSummary cSummary=pair.snd; | 138 | ComponentSummary cSummary=pair.snd; | |
| 139 | ComponentPolicy policy=new ComponentPolicy(component); | 139 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 140 | StringBuffer sb=new StringBuffer(); | 140 | StringBuffer sb=new StringBuffer(); | |
| 141 | boolean printComponent=false; | 141 | boolean printComponent=false; | |
| 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 143 | CGNode node=e.getKey(); | 143 | CGNode node=e.getKey(); | |
| 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 145 | boolean printMethod=false; | 145 | boolean printMethod=false; | |
| 146 | LockUsage lockUsage=LockUsage.EMPTY; | 146 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 147 | CompoundLockState compLS=e.getValue(); | 147 | CompoundLockState compLS=e.getValue(); | |
| 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 150 | WakeLockInstance wli=fs.getKey(); | 150 | WakeLockInstance wli=fs.getKey(); | |
| 151 | Set<SingleLockState> sls=fs.getValue(); | 151 | Set<SingleLockState> sls=fs.getValue(); | |
| 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 153 | lockUsage=getLockUsage(sl); | 153 | lockUsage=getLockUsage(sl); | |
| 154 | lockUsages.put(wli,lockUsage); | 154 | lockUsages.put(wli,lockUsage); | |
| 155 | if (lockUsage != LockUsage.EMPTY) { | 155 | if (lockUsage != LockUsage.EMPTY) { | |
| 156 | printMethod=true; | 156 | printMethod=true; | |
| 157 | } | 157 | } | |
| 158 | } | 158 | } | |
| 159 | if (printMethod) { | 159 | if (printMethod) { | |
| 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 161 | printComponent=true; | 161 | printComponent=true; | |
| 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 165 | WakeLockInstance key=fs.getKey(); | 165 | WakeLockInstance key=fs.getKey(); | |
| 166 | Set<SingleLockState> value=fs.getValue(); | 166 | Set<SingleLockState> value=fs.getValue(); | |
| 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 169 | } | 169 | } | |
| 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 171 | LockUsage lu=getLockUsage(mergedLS); | 171 | LockUsage lu=getLockUsage(mergedLS); | |
| 172 | if (component.isCallBack(node)) { | 172 | if (component.isCallBack(node)) { | |
| 173 | if (usageMap.containsKey(lu)) { | 173 | if (usageMap.containsKey(lu)) { | |
| 174 | usageMap.get(lu).add(Pair.make(component,node)); | 174 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 175 | } | 175 | } | |
| 176 | else { | 176 | else { | |
| 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 178 | set.add(Pair.make(component,node)); | 178 | set.add(Pair.make(component,node)); | |
| 179 | usageMap.put(lu,set); | 179 | usageMap.put(lu,set); | |
| 180 | } | 180 | } | |
| 181 | policy.addFact(node,mergedLS); | 181 | policy.addFact(node,mergedLS); | |
| 182 | } | 182 | } | |
| 183 | } | 183 | } | |
| 184 | } | 184 | } | |
| 185 | } | 185 | } | |
| 186 | if (printComponent) { | 186 | if (printComponent) { | |
| 187 | System.out.println(component.toString() + "\n" + sb.toString()); | 187 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 188 | policy.solveFacts(); | 188 | policy.solveFacts(); | |
| 189 | componentMap.put(component,policy.getLogger()); | 189 | componentMap.put(component,policy.getLogger()); | |
| 190 | } | 190 | } | |
| 191 | } | 191 | } | |
| 192 | System.out.println("==========================================\n"); | 192 | System.out.println("==========================================\n"); | |
| 193 | for ( LockUsage e : usageMap.keySet()) { | 193 | for ( LockUsage e : usageMap.keySet()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 196 | System.out.println(" " + s.toString()); | 196 | System.out.println(" " + s.toString()); | |
| 197 | } | 197 | } | |
| 198 | } | 198 | } | |
| 199 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 200 | for ( Component e : componentMap.keySet()) { | 200 | for ( Component e : componentMap.keySet()) { | |
| 201 | Logger logger=componentMap.get(e); | 201 | Logger logger=componentMap.get(e); | |
| 202 | if (!logger.isEmpty()) { | 202 | if (!logger.isEmpty()) { | |
| 203 | System.out.println(e.toString()); | 203 | System.out.println(e.toString()); | |
| 204 | System.out.println(logger.toString()); | 204 | System.out.println(logger.toString()); | |
| 205 | System.out.println("\n"); | 205 | System.out.println("\n"); | |
| 206 | } | 206 | } | |
| 207 | result=logger.getStringList(); | 207 | result=logger.getStringList(); | |
| 208 | } | 208 | } | |
| 209 | return result; | 209 | return result; | |
| 210 | } | 210 | } | |
| 211 | public class Logger extends ArrayList<Result> { | 211 | public class Logger extends ArrayList<Result> { | |
| 212 | private static final long serialVersionUID=4402714524487791090L; | 212 | private static final long serialVersionUID=4402714524487791090L; | |
| 213 | public void output(){ | 213 | public void output(){ | |
| 214 | for ( Result r : this) { | 214 | for ( Result r : this) { | |
| 215 | System.out.println(" " + r.getResultType().toString()); | 215 | System.out.println(" " + r.getResultType().toString()); | |
| 216 | } | 216 | } | |
| 217 | } | 217 | } | |
| 218 | public ArrayList<Result> getStringList(){ | 218 | public ArrayList<Result> getStringList(){ | |
| 219 | return this; | 219 | return this; | |
| 220 | } | 220 | } | |
| 221 | public String toString(){ | 221 | public String toString(){ | |
| 222 | StringBuffer result=new StringBuffer(); | 222 | StringBuffer result=new StringBuffer(); | |
| 223 | for ( Result r : this) { | 223 | for ( Result r : this) { | |
| 224 | result.append(r.toString() + "\n"); | 224 | result.append(r.toString() + "\n"); | |
| 225 | } | 225 | } | |
| 226 | return result.toString(); | 226 | return result.toString(); | |
| 227 | } | 227 | } | |
| 228 | } | 228 | } | |
| 229 | public class ComponentPolicy { | 229 | public class ComponentPolicy { | |
| 230 | private Component component; | 230 | private Component component; | |
| 231 | public ComponentPolicy( Component component){ | 231 | public ComponentPolicy( Component component){ | |
| 232 | this.component=component; | 232 | this.component=component; | |
| 233 | map=new HashMap<String,SingleLockState>(); | 233 | map=new HashMap<String,SingleLockState>(); | |
| 234 | logger=new Logger(); | 234 | logger=new Logger(); | |
| 235 | } | 235 | } | |
| 236 | private HashMap<String,SingleLockState> map; | 236 | private HashMap<String,SingleLockState> map; | |
| 237 | public void addFact( CGNode n, SingleLockState st){ | 237 | public void addFact( CGNode n, SingleLockState st){ | |
| 238 | map.put(n.getMethod().getName().toString(),st); | 238 | map.put(n.getMethod().getName().toString(),st); | |
| 239 | } | 239 | } | |
| 240 | private boolean unlocking( SingleLockState state){ | 240 | private boolean unlocking( SingleLockState state){ | |
| 241 | return (strongUnlocking(state) || weakUnlocking(state)); | 241 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 242 | } | 242 | } | |
| 243 | private boolean strongUnlocking( SingleLockState state){ | 243 | private boolean strongUnlocking( SingleLockState state){ | |
| 244 | if (state != null) { | 244 | if (state != null) { | |
| 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 246 | } | 246 | } | |
| 247 | return true; | 247 | return true; | |
| 248 | } | 248 | } | |
| 249 | private boolean weakUnlocking( SingleLockState state){ | 249 | private boolean weakUnlocking( SingleLockState state){ | |
| 250 | if (state != null) { | 250 | if (state != null) { | |
| 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 252 | } | 252 | } | |
| 253 | return true; | 253 | return true; | |
| 254 | } | 254 | } | |
| 255 | private boolean locking( SingleLockState onCreateState){ | 255 | private boolean locking( SingleLockState onCreateState){ | |
| 256 | if (onCreateState != null) { | 256 | if (onCreateState != null) { | |
| 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 258 | } | 258 | } | |
| 259 | return false; | 259 | return false; | |
| 260 | } | 260 | } | |
| 261 | private Logger logger; | 261 | private Logger logger; | |
| 262 | private void logNote( Result result){ | 262 | private void logNote( Result result){ | |
| 263 | logger.add(result); | 263 | logger.add(result); | |
| 264 | } | 264 | } | |
| 265 | public Logger getLogger(){ | 265 | public Logger getLogger(){ | |
| 266 | return logger; | 266 | return logger; | |
| 267 | } | 267 | } | |
| 268 | private SingleLockState getServiceOnStart(){ | 268 | private SingleLockState getServiceOnStart(){ | |
| 269 | SingleLockState onStart=map.get("onStart"); | 269 | SingleLockState onStart=map.get("onStart"); | |
| 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 271 | if (onStartCommand == null) { | 271 | if (onStartCommand == null) { | |
| 272 | return onStart; | 272 | return onStart; | |
| 273 | } | 273 | } | |
| 274 | else { | 274 | else { | |
| 275 | return onStartCommand; | 275 | return onStartCommand; | |
| 276 | } | 276 | } | |
| 277 | } | 277 | } | |
| 278 | /** | 278 | /** | |
| 279 | * TODO: make sure the same lock is locked and unlocked... | 279 | * TODO: make sure the same lock is locked and unlocked... | |
| 280 | */ | 280 | */ | |
| 281 | public void solveFacts(){ | 281 | public void solveFacts(){ | |
| 282 | if (component.getComponentType().equals("Activity")) { | 282 | if (component.getComponentType().equals("Activity")) { | |
| 283 | SingleLockState onCreateState=map.get("onCreate"); | 283 | SingleLockState onCreateState=map.get("onCreate"); | |
| 284 | if (locking(onCreateState)) { | 284 | if (locking(onCreateState)) { | |
| 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onStartState=map.get("onStart"); | 287 | SingleLockState onStartState=map.get("onStart"); | |
| 288 | if (locking(onStartState)) { | 288 | if (locking(onStartState)) { | |
| 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 290 | } | 290 | } | |
| 291 | SingleLockState onRestartState=map.get("onRestart"); | 291 | SingleLockState onRestartState=map.get("onRestart"); | |
| 292 | if (locking(onRestartState)) { | 292 | if (locking(onRestartState)) { | |
| 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 294 | } | 294 | } | |
| 295 | SingleLockState onPauseState=map.get("onPause"); | 295 | SingleLockState onPauseState=map.get("onPause"); | |
| 296 | if (!unlocking(onPauseState)) { | 296 | if (!unlocking(onPauseState)) { | |
| 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("Service")) { | 303 | if (component.getComponentType().equals("Service")) { | |
| 304 | SingleLockState onStartState=getServiceOnStart(); | 304 | SingleLockState onStartState=getServiceOnStart(); | |
| 305 | SingleLockState onDestroyState=map.get("onDestroy"); | 305 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | if (weakUnlocking(onDestroyState)) { | 309 | if (weakUnlocking(onDestroyState) && !str) { | |
| 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | if (component.getComponentType().equals("RunnableThread")) { | 313 | if (component.getComponentType().equals("RunnableThread")) { | |
| 314 | SingleLockState runState=map.get("run"); | 314 | SingleLockState runState=map.get("run"); | |
| 315 | if (locking(runState)) { | 315 | if (locking(runState)) { | |
| 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } | |
| 319 | if (component.getComponentType().equals("Handler")) { | 319 | if (component.getComponentType().equals("Handler")) { | |
| 320 | SingleLockState handleState=map.get("handleMessage"); | 320 | SingleLockState handleState=map.get("handleMessage"); | |
| 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 323 | } | 323 | } | |
| 324 | } | 324 | } | |
| 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 326 | SingleLockState onReceiveState=map.get("onReceive"); | 326 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 327 | if (locking(onReceiveState)) { | 327 | if (locking(onReceiveState)) { | |
| 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 329 | } | 329 | } | |
| 330 | } | 330 | } | |
| 331 | } | 331 | } | |
| 332 | } | 332 | } | |
| 333 | } | 333 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_072 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_073 | |||
|---|---|---|---|---|
|
333 lines 13380 bytes Last modified : Mon May 14 20:27:55 2012 |
333 lines 13399 bytes Last modified : Mon May 14 20:27:55 2012 |
|||
| 1 | //Time : 2012-04-26 20:49:39.030 | 1 | //Time : 2012-04-26 20:49:40.301 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | public class AnalysisResults { | 18 | public class AnalysisResults { | |
| 19 | /** | 19 | /** | |
| 20 | * Main structures that hold the analysis results for every component | 20 | * Main structures that hold the analysis results for every component | |
| 21 | */ | 21 | */ | |
| 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 23 | public class ComponentSummary { | 23 | public class ComponentSummary { | |
| 24 | private Component component; | 24 | private Component component; | |
| 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 27 | public ComponentSummary( Component c){ | 27 | public ComponentSummary( Component c){ | |
| 28 | this.component=c; | 28 | this.component=c; | |
| 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 31 | } | 31 | } | |
| 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 33 | return allExitStates; | 33 | return allExitStates; | |
| 34 | } | 34 | } | |
| 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 36 | allExitStates.put(n,st); | 36 | allExitStates.put(n,st); | |
| 37 | } | 37 | } | |
| 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 39 | callBackExitStates.put(cb,st); | 39 | callBackExitStates.put(cb,st); | |
| 40 | } | 40 | } | |
| 41 | public CompoundLockState getStateForMethod( String method){ | 41 | public CompoundLockState getStateForMethod( String method){ | |
| 42 | return allExitStates.get(method); | 42 | return allExitStates.get(method); | |
| 43 | } | 43 | } | |
| 44 | public String toString(){ | 44 | public String toString(){ | |
| 45 | StringBuffer sb=new StringBuffer(); | 45 | StringBuffer sb=new StringBuffer(); | |
| 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 47 | CGNode next=it.next(); | 47 | CGNode next=it.next(); | |
| 48 | String name=next.getMethod().getName().toString(); | 48 | String name=next.getMethod().getName().toString(); | |
| 49 | CompoundLockState stateForMethod=getStateForMethod(name); | 49 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 50 | if (stateForMethod != null) { | 50 | if (stateForMethod != null) { | |
| 51 | sb.append(name + ":\n" + stateForMethod.toString()); | 51 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 52 | } | 52 | } | |
| 53 | } | 53 | } | |
| 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 55 | if (callbacks != null) { | 55 | if (callbacks != null) { | |
| 56 | if (callbacks.size() > 0) { | 56 | if (callbacks.size() > 0) { | |
| 57 | sb.append("Callbacks:\n"); | 57 | sb.append("Callbacks:\n"); | |
| 58 | for ( CallBack cb : callbacks) { | 58 | for ( CallBack cb : callbacks) { | |
| 59 | String name=cb.getName(); | 59 | String name=cb.getName(); | |
| 60 | ; | 60 | ; | |
| 61 | CompoundLockState stateForMethod=getStateForMethod(name); | 61 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 62 | if (stateForMethod != null) { | 62 | if (stateForMethod != null) { | |
| 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 64 | } | 64 | } | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | return null; | 68 | return null; | |
| 69 | } | 69 | } | |
| 70 | } | 70 | } | |
| 71 | public AnalysisResults(){ | 71 | public AnalysisResults(){ | |
| 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 73 | } | 73 | } | |
| 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 76 | public static class Result { | 76 | public static class Result { | |
| 77 | private ResultType resultType; | 77 | private ResultType resultType; | |
| 78 | private String message; | 78 | private String message; | |
| 79 | public ResultType getResultType(){ | 79 | public ResultType getResultType(){ | |
| 80 | return resultType; | 80 | return resultType; | |
| 81 | } | 81 | } | |
| 82 | public String getMessage(){ | 82 | public String getMessage(){ | |
| 83 | return message; | 83 | return message; | |
| 84 | } | 84 | } | |
| 85 | public Result( ResultType rt, String msg){ | 85 | public Result( ResultType rt, String msg){ | |
| 86 | message=msg; | 86 | message=msg; | |
| 87 | resultType=rt; | 87 | resultType=rt; | |
| 88 | } | 88 | } | |
| 89 | public String toString(){ | 89 | public String toString(){ | |
| 90 | return (resultType.name() + " " + message); | 90 | return (resultType.name() + " " + message); | |
| 91 | } | 91 | } | |
| 92 | } | 92 | } | |
| 93 | /** | 93 | /** | |
| 94 | * Invoke this after the component has been analyzed | 94 | * Invoke this after the component has been analyzed | |
| 95 | * @param component | 95 | * @param component | |
| 96 | */ | 96 | */ | |
| 97 | public void createComponentSummary( Component component){ | 97 | public void createComponentSummary( Component component){ | |
| 98 | ComponentSummary componentSummary=new ComponentSummary(component); | 98 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 100 | CGNode next=it.next(); | 100 | CGNode next=it.next(); | |
| 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 102 | if (exitState != null) { | 102 | if (exitState != null) { | |
| 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 104 | componentSummary.registerNodeState(next,compoundLockState); | 104 | componentSummary.registerNodeState(next,compoundLockState); | |
| 105 | } | 105 | } | |
| 106 | } | 106 | } | |
| 107 | allStates.add(Pair.make(component,componentSummary)); | 107 | allStates.add(Pair.make(component,componentSummary)); | |
| 108 | } | 108 | } | |
| 109 | private LockUsage getLockUsage( SingleLockState runState){ | 109 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 110 | if (runState != null) { | 110 | if (runState != null) { | |
| 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 112 | return LockUsage.LOCKING; | 112 | return LockUsage.LOCKING; | |
| 113 | } | 113 | } | |
| 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 115 | return LockUsage.EMPTY; | 115 | return LockUsage.EMPTY; | |
| 116 | } | 116 | } | |
| 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 118 | return LockUsage.FULL_UNLOCKING; | 118 | return LockUsage.FULL_UNLOCKING; | |
| 119 | } | 119 | } | |
| 120 | else if (runState.isMaybeReleased()) { | 120 | else if (runState.isMaybeReleased()) { | |
| 121 | return LockUsage.UNLOCKING; | 121 | return LockUsage.UNLOCKING; | |
| 122 | } | 122 | } | |
| 123 | else { | 123 | else { | |
| 124 | return LockUsage.UNKNOWN_STATE; | 124 | return LockUsage.UNKNOWN_STATE; | |
| 125 | } | 125 | } | |
| 126 | } | 126 | } | |
| 127 | else { | 127 | else { | |
| 128 | return LockUsage.EMPTY; | 128 | return LockUsage.EMPTY; | |
| 129 | } | 129 | } | |
| 130 | } | 130 | } | |
| 131 | public ArrayList<Result> processResults(){ | 131 | public ArrayList<Result> processResults(){ | |
| 132 | ArrayList<Result> result=new ArrayList<Result>(); | 132 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 133 | System.out.println("\n=========================================="); | 133 | System.out.println("\n=========================================="); | |
| 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 137 | Component component=pair.fst; | 137 | Component component=pair.fst; | |
| 138 | ComponentSummary cSummary=pair.snd; | 138 | ComponentSummary cSummary=pair.snd; | |
| 139 | ComponentPolicy policy=new ComponentPolicy(component); | 139 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 140 | StringBuffer sb=new StringBuffer(); | 140 | StringBuffer sb=new StringBuffer(); | |
| 141 | boolean printComponent=false; | 141 | boolean printComponent=false; | |
| 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 143 | CGNode node=e.getKey(); | 143 | CGNode node=e.getKey(); | |
| 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 145 | boolean printMethod=false; | 145 | boolean printMethod=false; | |
| 146 | LockUsage lockUsage=LockUsage.EMPTY; | 146 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 147 | CompoundLockState compLS=e.getValue(); | 147 | CompoundLockState compLS=e.getValue(); | |
| 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 150 | WakeLockInstance wli=fs.getKey(); | 150 | WakeLockInstance wli=fs.getKey(); | |
| 151 | Set<SingleLockState> sls=fs.getValue(); | 151 | Set<SingleLockState> sls=fs.getValue(); | |
| 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 153 | lockUsage=getLockUsage(sl); | 153 | lockUsage=getLockUsage(sl); | |
| 154 | lockUsages.put(wli,lockUsage); | 154 | lockUsages.put(wli,lockUsage); | |
| 155 | if (lockUsage != LockUsage.EMPTY) { | 155 | if (lockUsage != LockUsage.EMPTY) { | |
| 156 | printMethod=true; | 156 | printMethod=true; | |
| 157 | } | 157 | } | |
| 158 | } | 158 | } | |
| 159 | if (printMethod) { | 159 | if (printMethod) { | |
| 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 161 | printComponent=true; | 161 | printComponent=true; | |
| 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 165 | WakeLockInstance key=fs.getKey(); | 165 | WakeLockInstance key=fs.getKey(); | |
| 166 | Set<SingleLockState> value=fs.getValue(); | 166 | Set<SingleLockState> value=fs.getValue(); | |
| 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 169 | } | 169 | } | |
| 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 171 | LockUsage lu=getLockUsage(mergedLS); | 171 | LockUsage lu=getLockUsage(mergedLS); | |
| 172 | if (component.isCallBack(node)) { | 172 | if (component.isCallBack(node)) { | |
| 173 | if (usageMap.containsKey(lu)) { | 173 | if (usageMap.containsKey(lu)) { | |
| 174 | usageMap.get(lu).add(Pair.make(component,node)); | 174 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 175 | } | 175 | } | |
| 176 | else { | 176 | else { | |
| 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 178 | set.add(Pair.make(component,node)); | 178 | set.add(Pair.make(component,node)); | |
| 179 | usageMap.put(lu,set); | 179 | usageMap.put(lu,set); | |
| 180 | } | 180 | } | |
| 181 | policy.addFact(node,mergedLS); | 181 | policy.addFact(node,mergedLS); | |
| 182 | } | 182 | } | |
| 183 | } | 183 | } | |
| 184 | } | 184 | } | |
| 185 | } | 185 | } | |
| 186 | if (printComponent) { | 186 | if (printComponent) { | |
| 187 | System.out.println(component.toString() + "\n" + sb.toString()); | 187 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 188 | policy.solveFacts(); | 188 | policy.solveFacts(); | |
| 189 | componentMap.put(component,policy.getLogger()); | 189 | componentMap.put(component,policy.getLogger()); | |
| 190 | } | 190 | } | |
| 191 | } | 191 | } | |
| 192 | System.out.println("==========================================\n"); | 192 | System.out.println("==========================================\n"); | |
| 193 | for ( LockUsage e : usageMap.keySet()) { | 193 | for ( LockUsage e : usageMap.keySet()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 196 | System.out.println(" " + s.toString()); | 196 | System.out.println(" " + s.toString()); | |
| 197 | } | 197 | } | |
| 198 | } | 198 | } | |
| 199 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 200 | for ( Component e : componentMap.keySet()) { | 200 | for ( Component e : componentMap.keySet()) { | |
| 201 | Logger logger=componentMap.get(e); | 201 | Logger logger=componentMap.get(e); | |
| 202 | if (!logger.isEmpty()) { | 202 | if (!logger.isEmpty()) { | |
| 203 | System.out.println(e.toString()); | 203 | System.out.println(e.toString()); | |
| 204 | System.out.println(logger.toString()); | 204 | System.out.println(logger.toString()); | |
| 205 | System.out.println("\n"); | 205 | System.out.println("\n"); | |
| 206 | } | 206 | } | |
| 207 | result=logger.getStringList(); | 207 | result=logger.getStringList(); | |
| 208 | } | 208 | } | |
| 209 | return result; | 209 | return result; | |
| 210 | } | 210 | } | |
| 211 | public class Logger extends ArrayList<Result> { | 211 | public class Logger extends ArrayList<Result> { | |
| 212 | private static final long serialVersionUID=4402714524487791090L; | 212 | private static final long serialVersionUID=4402714524487791090L; | |
| 213 | public void output(){ | 213 | public void output(){ | |
| 214 | for ( Result r : this) { | 214 | for ( Result r : this) { | |
| 215 | System.out.println(" " + r.getResultType().toString()); | 215 | System.out.println(" " + r.getResultType().toString()); | |
| 216 | } | 216 | } | |
| 217 | } | 217 | } | |
| 218 | public ArrayList<Result> getStringList(){ | 218 | public ArrayList<Result> getStringList(){ | |
| 219 | return this; | 219 | return this; | |
| 220 | } | 220 | } | |
| 221 | public String toString(){ | 221 | public String toString(){ | |
| 222 | StringBuffer result=new StringBuffer(); | 222 | StringBuffer result=new StringBuffer(); | |
| 223 | for ( Result r : this) { | 223 | for ( Result r : this) { | |
| 224 | result.append(r.toString() + "\n"); | 224 | result.append(r.toString() + "\n"); | |
| 225 | } | 225 | } | |
| 226 | return result.toString(); | 226 | return result.toString(); | |
| 227 | } | 227 | } | |
| 228 | } | 228 | } | |
| 229 | public class ComponentPolicy { | 229 | public class ComponentPolicy { | |
| 230 | private Component component; | 230 | private Component component; | |
| 231 | public ComponentPolicy( Component component){ | 231 | public ComponentPolicy( Component component){ | |
| 232 | this.component=component; | 232 | this.component=component; | |
| 233 | map=new HashMap<String,SingleLockState>(); | 233 | map=new HashMap<String,SingleLockState>(); | |
| 234 | logger=new Logger(); | 234 | logger=new Logger(); | |
| 235 | } | 235 | } | |
| 236 | private HashMap<String,SingleLockState> map; | 236 | private HashMap<String,SingleLockState> map; | |
| 237 | public void addFact( CGNode n, SingleLockState st){ | 237 | public void addFact( CGNode n, SingleLockState st){ | |
| 238 | map.put(n.getMethod().getName().toString(),st); | 238 | map.put(n.getMethod().getName().toString(),st); | |
| 239 | } | 239 | } | |
| 240 | private boolean unlocking( SingleLockState state){ | 240 | private boolean unlocking( SingleLockState state){ | |
| 241 | return (strongUnlocking(state) || weakUnlocking(state)); | 241 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 242 | } | 242 | } | |
| 243 | private boolean strongUnlocking( SingleLockState state){ | 243 | private boolean strongUnlocking( SingleLockState state){ | |
| 244 | if (state != null) { | 244 | if (state != null) { | |
| 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 246 | } | 246 | } | |
| 247 | return true; | 247 | return true; | |
| 248 | } | 248 | } | |
| 249 | private boolean weakUnlocking( SingleLockState state){ | 249 | private boolean weakUnlocking( SingleLockState state){ | |
| 250 | if (state != null) { | 250 | if (state != null) { | |
| 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 252 | } | 252 | } | |
| 253 | return true; | 253 | return true; | |
| 254 | } | 254 | } | |
| 255 | private boolean locking( SingleLockState onCreateState){ | 255 | private boolean locking( SingleLockState onCreateState){ | |
| 256 | if (onCreateState != null) { | 256 | if (onCreateState != null) { | |
| 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 258 | } | 258 | } | |
| 259 | return false; | 259 | return false; | |
| 260 | } | 260 | } | |
| 261 | private Logger logger; | 261 | private Logger logger; | |
| 262 | private void logNote( Result result){ | 262 | private void logNote( Result result){ | |
| 263 | logger.add(result); | 263 | logger.add(result); | |
| 264 | } | 264 | } | |
| 265 | public Logger getLogger(){ | 265 | public Logger getLogger(){ | |
| 266 | return logger; | 266 | return logger; | |
| 267 | } | 267 | } | |
| 268 | private SingleLockState getServiceOnStart(){ | 268 | private SingleLockState getServiceOnStart(){ | |
| 269 | SingleLockState onStart=map.get("onStart"); | 269 | SingleLockState onStart=map.get("onStart"); | |
| 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 271 | if (onStartCommand == null) { | 271 | if (onStartCommand == null) { | |
| 272 | return onStart; | 272 | return onStart; | |
| 273 | } | 273 | } | |
| 274 | else { | 274 | else { | |
| 275 | return onStartCommand; | 275 | return onStartCommand; | |
| 276 | } | 276 | } | |
| 277 | } | 277 | } | |
| 278 | /** | 278 | /** | |
| 279 | * TODO: make sure the same lock is locked and unlocked... | 279 | * TODO: make sure the same lock is locked and unlocked... | |
| 280 | */ | 280 | */ | |
| 281 | public void solveFacts(){ | 281 | public void solveFacts(){ | |
| 282 | if (component.getComponentType().equals("Activity")) { | 282 | if (component.getComponentType().equals("Activity")) { | |
| 283 | SingleLockState onCreateState=map.get("onCreate"); | 283 | SingleLockState onCreateState=map.get("onCreate"); | |
| 284 | if (locking(onCreateState)) { | 284 | if (locking(onCreateState)) { | |
| 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onStartState=map.get("onStart"); | 287 | SingleLockState onStartState=map.get("onStart"); | |
| 288 | if (locking(onStartState)) { | 288 | if (locking(onStartState)) { | |
| 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 290 | } | 290 | } | |
| 291 | SingleLockState onRestartState=map.get("onRestart"); | 291 | SingleLockState onRestartState=map.get("onRestart"); | |
| 292 | if (locking(onRestartState)) { | 292 | if (locking(onRestartState)) { | |
| 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 294 | } | 294 | } | |
| 295 | SingleLockState onPauseState=map.get("onPause"); | 295 | SingleLockState onPauseState=map.get("onPause"); | |
| 296 | if (!unlocking(onPauseState)) { | 296 | if (!unlocking(onPauseState)) { | |
| 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("Service")) { | 303 | if (component.getComponentType().equals("Service")) { | |
| 304 | SingleLockState onStartState=getServiceOnStart(); | 304 | SingleLockState onStartState=getServiceOnStart(); | |
| 305 | SingleLockState onDestroyState=map.get("onDestroy"); | 305 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | if (weakUnlocking(onDestroyState) && !str) { | 309 | if (weakUnlocking(onDestroyState) && !strongUnlocking(state)) { | |
| 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | if (component.getComponentType().equals("RunnableThread")) { | 313 | if (component.getComponentType().equals("RunnableThread")) { | |
| 314 | SingleLockState runState=map.get("run"); | 314 | SingleLockState runState=map.get("run"); | |
| 315 | if (locking(runState)) { | 315 | if (locking(runState)) { | |
| 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } | |
| 319 | if (component.getComponentType().equals("Handler")) { | 319 | if (component.getComponentType().equals("Handler")) { | |
| 320 | SingleLockState handleState=map.get("handleMessage"); | 320 | SingleLockState handleState=map.get("handleMessage"); | |
| 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 323 | } | 323 | } | |
| 324 | } | 324 | } | |
| 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 326 | SingleLockState onReceiveState=map.get("onReceive"); | 326 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 327 | if (locking(onReceiveState)) { | 327 | if (locking(onReceiveState)) { | |
| 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 329 | } | 329 | } | |
| 330 | } | 330 | } | |
| 331 | } | 331 | } | |
| 332 | } | 332 | } | |
| 333 | } | 333 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_073 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_074 | |||
|---|---|---|---|---|
|
333 lines 13399 bytes Last modified : Mon May 14 20:27:55 2012 |
333 lines 13408 bytes Last modified : Mon May 14 20:27:55 2012 |
|||
| 1 | //Time : 2012-04-26 20:49:40.301 | 1 | //Time : 2012-04-26 20:49:44.084 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | public class AnalysisResults { | 18 | public class AnalysisResults { | |
| 19 | /** | 19 | /** | |
| 20 | * Main structures that hold the analysis results for every component | 20 | * Main structures that hold the analysis results for every component | |
| 21 | */ | 21 | */ | |
| 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 23 | public class ComponentSummary { | 23 | public class ComponentSummary { | |
| 24 | private Component component; | 24 | private Component component; | |
| 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 27 | public ComponentSummary( Component c){ | 27 | public ComponentSummary( Component c){ | |
| 28 | this.component=c; | 28 | this.component=c; | |
| 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 31 | } | 31 | } | |
| 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 33 | return allExitStates; | 33 | return allExitStates; | |
| 34 | } | 34 | } | |
| 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 36 | allExitStates.put(n,st); | 36 | allExitStates.put(n,st); | |
| 37 | } | 37 | } | |
| 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 39 | callBackExitStates.put(cb,st); | 39 | callBackExitStates.put(cb,st); | |
| 40 | } | 40 | } | |
| 41 | public CompoundLockState getStateForMethod( String method){ | 41 | public CompoundLockState getStateForMethod( String method){ | |
| 42 | return allExitStates.get(method); | 42 | return allExitStates.get(method); | |
| 43 | } | 43 | } | |
| 44 | public String toString(){ | 44 | public String toString(){ | |
| 45 | StringBuffer sb=new StringBuffer(); | 45 | StringBuffer sb=new StringBuffer(); | |
| 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 47 | CGNode next=it.next(); | 47 | CGNode next=it.next(); | |
| 48 | String name=next.getMethod().getName().toString(); | 48 | String name=next.getMethod().getName().toString(); | |
| 49 | CompoundLockState stateForMethod=getStateForMethod(name); | 49 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 50 | if (stateForMethod != null) { | 50 | if (stateForMethod != null) { | |
| 51 | sb.append(name + ":\n" + stateForMethod.toString()); | 51 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 52 | } | 52 | } | |
| 53 | } | 53 | } | |
| 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 55 | if (callbacks != null) { | 55 | if (callbacks != null) { | |
| 56 | if (callbacks.size() > 0) { | 56 | if (callbacks.size() > 0) { | |
| 57 | sb.append("Callbacks:\n"); | 57 | sb.append("Callbacks:\n"); | |
| 58 | for ( CallBack cb : callbacks) { | 58 | for ( CallBack cb : callbacks) { | |
| 59 | String name=cb.getName(); | 59 | String name=cb.getName(); | |
| 60 | ; | 60 | ; | |
| 61 | CompoundLockState stateForMethod=getStateForMethod(name); | 61 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 62 | if (stateForMethod != null) { | 62 | if (stateForMethod != null) { | |
| 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 64 | } | 64 | } | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | return null; | 68 | return null; | |
| 69 | } | 69 | } | |
| 70 | } | 70 | } | |
| 71 | public AnalysisResults(){ | 71 | public AnalysisResults(){ | |
| 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 73 | } | 73 | } | |
| 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 76 | public static class Result { | 76 | public static class Result { | |
| 77 | private ResultType resultType; | 77 | private ResultType resultType; | |
| 78 | private String message; | 78 | private String message; | |
| 79 | public ResultType getResultType(){ | 79 | public ResultType getResultType(){ | |
| 80 | return resultType; | 80 | return resultType; | |
| 81 | } | 81 | } | |
| 82 | public String getMessage(){ | 82 | public String getMessage(){ | |
| 83 | return message; | 83 | return message; | |
| 84 | } | 84 | } | |
| 85 | public Result( ResultType rt, String msg){ | 85 | public Result( ResultType rt, String msg){ | |
| 86 | message=msg; | 86 | message=msg; | |
| 87 | resultType=rt; | 87 | resultType=rt; | |
| 88 | } | 88 | } | |
| 89 | public String toString(){ | 89 | public String toString(){ | |
| 90 | return (resultType.name() + " " + message); | 90 | return (resultType.name() + " " + message); | |
| 91 | } | 91 | } | |
| 92 | } | 92 | } | |
| 93 | /** | 93 | /** | |
| 94 | * Invoke this after the component has been analyzed | 94 | * Invoke this after the component has been analyzed | |
| 95 | * @param component | 95 | * @param component | |
| 96 | */ | 96 | */ | |
| 97 | public void createComponentSummary( Component component){ | 97 | public void createComponentSummary( Component component){ | |
| 98 | ComponentSummary componentSummary=new ComponentSummary(component); | 98 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 100 | CGNode next=it.next(); | 100 | CGNode next=it.next(); | |
| 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 102 | if (exitState != null) { | 102 | if (exitState != null) { | |
| 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 104 | componentSummary.registerNodeState(next,compoundLockState); | 104 | componentSummary.registerNodeState(next,compoundLockState); | |
| 105 | } | 105 | } | |
| 106 | } | 106 | } | |
| 107 | allStates.add(Pair.make(component,componentSummary)); | 107 | allStates.add(Pair.make(component,componentSummary)); | |
| 108 | } | 108 | } | |
| 109 | private LockUsage getLockUsage( SingleLockState runState){ | 109 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 110 | if (runState != null) { | 110 | if (runState != null) { | |
| 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 112 | return LockUsage.LOCKING; | 112 | return LockUsage.LOCKING; | |
| 113 | } | 113 | } | |
| 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 115 | return LockUsage.EMPTY; | 115 | return LockUsage.EMPTY; | |
| 116 | } | 116 | } | |
| 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 118 | return LockUsage.FULL_UNLOCKING; | 118 | return LockUsage.FULL_UNLOCKING; | |
| 119 | } | 119 | } | |
| 120 | else if (runState.isMaybeReleased()) { | 120 | else if (runState.isMaybeReleased()) { | |
| 121 | return LockUsage.UNLOCKING; | 121 | return LockUsage.UNLOCKING; | |
| 122 | } | 122 | } | |
| 123 | else { | 123 | else { | |
| 124 | return LockUsage.UNKNOWN_STATE; | 124 | return LockUsage.UNKNOWN_STATE; | |
| 125 | } | 125 | } | |
| 126 | } | 126 | } | |
| 127 | else { | 127 | else { | |
| 128 | return LockUsage.EMPTY; | 128 | return LockUsage.EMPTY; | |
| 129 | } | 129 | } | |
| 130 | } | 130 | } | |
| 131 | public ArrayList<Result> processResults(){ | 131 | public ArrayList<Result> processResults(){ | |
| 132 | ArrayList<Result> result=new ArrayList<Result>(); | 132 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 133 | System.out.println("\n=========================================="); | 133 | System.out.println("\n=========================================="); | |
| 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 137 | Component component=pair.fst; | 137 | Component component=pair.fst; | |
| 138 | ComponentSummary cSummary=pair.snd; | 138 | ComponentSummary cSummary=pair.snd; | |
| 139 | ComponentPolicy policy=new ComponentPolicy(component); | 139 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 140 | StringBuffer sb=new StringBuffer(); | 140 | StringBuffer sb=new StringBuffer(); | |
| 141 | boolean printComponent=false; | 141 | boolean printComponent=false; | |
| 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 143 | CGNode node=e.getKey(); | 143 | CGNode node=e.getKey(); | |
| 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 145 | boolean printMethod=false; | 145 | boolean printMethod=false; | |
| 146 | LockUsage lockUsage=LockUsage.EMPTY; | 146 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 147 | CompoundLockState compLS=e.getValue(); | 147 | CompoundLockState compLS=e.getValue(); | |
| 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 150 | WakeLockInstance wli=fs.getKey(); | 150 | WakeLockInstance wli=fs.getKey(); | |
| 151 | Set<SingleLockState> sls=fs.getValue(); | 151 | Set<SingleLockState> sls=fs.getValue(); | |
| 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 153 | lockUsage=getLockUsage(sl); | 153 | lockUsage=getLockUsage(sl); | |
| 154 | lockUsages.put(wli,lockUsage); | 154 | lockUsages.put(wli,lockUsage); | |
| 155 | if (lockUsage != LockUsage.EMPTY) { | 155 | if (lockUsage != LockUsage.EMPTY) { | |
| 156 | printMethod=true; | 156 | printMethod=true; | |
| 157 | } | 157 | } | |
| 158 | } | 158 | } | |
| 159 | if (printMethod) { | 159 | if (printMethod) { | |
| 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 161 | printComponent=true; | 161 | printComponent=true; | |
| 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 165 | WakeLockInstance key=fs.getKey(); | 165 | WakeLockInstance key=fs.getKey(); | |
| 166 | Set<SingleLockState> value=fs.getValue(); | 166 | Set<SingleLockState> value=fs.getValue(); | |
| 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 169 | } | 169 | } | |
| 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 171 | LockUsage lu=getLockUsage(mergedLS); | 171 | LockUsage lu=getLockUsage(mergedLS); | |
| 172 | if (component.isCallBack(node)) { | 172 | if (component.isCallBack(node)) { | |
| 173 | if (usageMap.containsKey(lu)) { | 173 | if (usageMap.containsKey(lu)) { | |
| 174 | usageMap.get(lu).add(Pair.make(component,node)); | 174 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 175 | } | 175 | } | |
| 176 | else { | 176 | else { | |
| 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 178 | set.add(Pair.make(component,node)); | 178 | set.add(Pair.make(component,node)); | |
| 179 | usageMap.put(lu,set); | 179 | usageMap.put(lu,set); | |
| 180 | } | 180 | } | |
| 181 | policy.addFact(node,mergedLS); | 181 | policy.addFact(node,mergedLS); | |
| 182 | } | 182 | } | |
| 183 | } | 183 | } | |
| 184 | } | 184 | } | |
| 185 | } | 185 | } | |
| 186 | if (printComponent) { | 186 | if (printComponent) { | |
| 187 | System.out.println(component.toString() + "\n" + sb.toString()); | 187 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 188 | policy.solveFacts(); | 188 | policy.solveFacts(); | |
| 189 | componentMap.put(component,policy.getLogger()); | 189 | componentMap.put(component,policy.getLogger()); | |
| 190 | } | 190 | } | |
| 191 | } | 191 | } | |
| 192 | System.out.println("==========================================\n"); | 192 | System.out.println("==========================================\n"); | |
| 193 | for ( LockUsage e : usageMap.keySet()) { | 193 | for ( LockUsage e : usageMap.keySet()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 196 | System.out.println(" " + s.toString()); | 196 | System.out.println(" " + s.toString()); | |
| 197 | } | 197 | } | |
| 198 | } | 198 | } | |
| 199 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 200 | for ( Component e : componentMap.keySet()) { | 200 | for ( Component e : componentMap.keySet()) { | |
| 201 | Logger logger=componentMap.get(e); | 201 | Logger logger=componentMap.get(e); | |
| 202 | if (!logger.isEmpty()) { | 202 | if (!logger.isEmpty()) { | |
| 203 | System.out.println(e.toString()); | 203 | System.out.println(e.toString()); | |
| 204 | System.out.println(logger.toString()); | 204 | System.out.println(logger.toString()); | |
| 205 | System.out.println("\n"); | 205 | System.out.println("\n"); | |
| 206 | } | 206 | } | |
| 207 | result=logger.getStringList(); | 207 | result=logger.getStringList(); | |
| 208 | } | 208 | } | |
| 209 | return result; | 209 | return result; | |
| 210 | } | 210 | } | |
| 211 | public class Logger extends ArrayList<Result> { | 211 | public class Logger extends ArrayList<Result> { | |
| 212 | private static final long serialVersionUID=4402714524487791090L; | 212 | private static final long serialVersionUID=4402714524487791090L; | |
| 213 | public void output(){ | 213 | public void output(){ | |
| 214 | for ( Result r : this) { | 214 | for ( Result r : this) { | |
| 215 | System.out.println(" " + r.getResultType().toString()); | 215 | System.out.println(" " + r.getResultType().toString()); | |
| 216 | } | 216 | } | |
| 217 | } | 217 | } | |
| 218 | public ArrayList<Result> getStringList(){ | 218 | public ArrayList<Result> getStringList(){ | |
| 219 | return this; | 219 | return this; | |
| 220 | } | 220 | } | |
| 221 | public String toString(){ | 221 | public String toString(){ | |
| 222 | StringBuffer result=new StringBuffer(); | 222 | StringBuffer result=new StringBuffer(); | |
| 223 | for ( Result r : this) { | 223 | for ( Result r : this) { | |
| 224 | result.append(r.toString() + "\n"); | 224 | result.append(r.toString() + "\n"); | |
| 225 | } | 225 | } | |
| 226 | return result.toString(); | 226 | return result.toString(); | |
| 227 | } | 227 | } | |
| 228 | } | 228 | } | |
| 229 | public class ComponentPolicy { | 229 | public class ComponentPolicy { | |
| 230 | private Component component; | 230 | private Component component; | |
| 231 | public ComponentPolicy( Component component){ | 231 | public ComponentPolicy( Component component){ | |
| 232 | this.component=component; | 232 | this.component=component; | |
| 233 | map=new HashMap<String,SingleLockState>(); | 233 | map=new HashMap<String,SingleLockState>(); | |
| 234 | logger=new Logger(); | 234 | logger=new Logger(); | |
| 235 | } | 235 | } | |
| 236 | private HashMap<String,SingleLockState> map; | 236 | private HashMap<String,SingleLockState> map; | |
| 237 | public void addFact( CGNode n, SingleLockState st){ | 237 | public void addFact( CGNode n, SingleLockState st){ | |
| 238 | map.put(n.getMethod().getName().toString(),st); | 238 | map.put(n.getMethod().getName().toString(),st); | |
| 239 | } | 239 | } | |
| 240 | private boolean unlocking( SingleLockState state){ | 240 | private boolean unlocking( SingleLockState state){ | |
| 241 | return (strongUnlocking(state) || weakUnlocking(state)); | 241 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 242 | } | 242 | } | |
| 243 | private boolean strongUnlocking( SingleLockState state){ | 243 | private boolean strongUnlocking( SingleLockState state){ | |
| 244 | if (state != null) { | 244 | if (state != null) { | |
| 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 246 | } | 246 | } | |
| 247 | return true; | 247 | return true; | |
| 248 | } | 248 | } | |
| 249 | private boolean weakUnlocking( SingleLockState state){ | 249 | private boolean weakUnlocking( SingleLockState state){ | |
| 250 | if (state != null) { | 250 | if (state != null) { | |
| 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 252 | } | 252 | } | |
| 253 | return true; | 253 | return true; | |
| 254 | } | 254 | } | |
| 255 | private boolean locking( SingleLockState onCreateState){ | 255 | private boolean locking( SingleLockState onCreateState){ | |
| 256 | if (onCreateState != null) { | 256 | if (onCreateState != null) { | |
| 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 258 | } | 258 | } | |
| 259 | return false; | 259 | return false; | |
| 260 | } | 260 | } | |
| 261 | private Logger logger; | 261 | private Logger logger; | |
| 262 | private void logNote( Result result){ | 262 | private void logNote( Result result){ | |
| 263 | logger.add(result); | 263 | logger.add(result); | |
| 264 | } | 264 | } | |
| 265 | public Logger getLogger(){ | 265 | public Logger getLogger(){ | |
| 266 | return logger; | 266 | return logger; | |
| 267 | } | 267 | } | |
| 268 | private SingleLockState getServiceOnStart(){ | 268 | private SingleLockState getServiceOnStart(){ | |
| 269 | SingleLockState onStart=map.get("onStart"); | 269 | SingleLockState onStart=map.get("onStart"); | |
| 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 271 | if (onStartCommand == null) { | 271 | if (onStartCommand == null) { | |
| 272 | return onStart; | 272 | return onStart; | |
| 273 | } | 273 | } | |
| 274 | else { | 274 | else { | |
| 275 | return onStartCommand; | 275 | return onStartCommand; | |
| 276 | } | 276 | } | |
| 277 | } | 277 | } | |
| 278 | /** | 278 | /** | |
| 279 | * TODO: make sure the same lock is locked and unlocked... | 279 | * TODO: make sure the same lock is locked and unlocked... | |
| 280 | */ | 280 | */ | |
| 281 | public void solveFacts(){ | 281 | public void solveFacts(){ | |
| 282 | if (component.getComponentType().equals("Activity")) { | 282 | if (component.getComponentType().equals("Activity")) { | |
| 283 | SingleLockState onCreateState=map.get("onCreate"); | 283 | SingleLockState onCreateState=map.get("onCreate"); | |
| 284 | if (locking(onCreateState)) { | 284 | if (locking(onCreateState)) { | |
| 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onStartState=map.get("onStart"); | 287 | SingleLockState onStartState=map.get("onStart"); | |
| 288 | if (locking(onStartState)) { | 288 | if (locking(onStartState)) { | |
| 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 290 | } | 290 | } | |
| 291 | SingleLockState onRestartState=map.get("onRestart"); | 291 | SingleLockState onRestartState=map.get("onRestart"); | |
| 292 | if (locking(onRestartState)) { | 292 | if (locking(onRestartState)) { | |
| 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 294 | } | 294 | } | |
| 295 | SingleLockState onPauseState=map.get("onPause"); | 295 | SingleLockState onPauseState=map.get("onPause"); | |
| 296 | if (!unlocking(onPauseState)) { | 296 | if (!unlocking(onPauseState)) { | |
| 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("Service")) { | 303 | if (component.getComponentType().equals("Service")) { | |
| 304 | SingleLockState onStartState=getServiceOnStart(); | 304 | SingleLockState onStartState=getServiceOnStart(); | |
| 305 | SingleLockState onDestroyState=map.get("onDestroy"); | 305 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | if (weakUnlocking(onDestroyState) && !strongUnlocking(state)) { | 309 | if (weakUnlocking(onDestroyState) && !strongUnlocking(onDestroyState)) { | |
| 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | if (component.getComponentType().equals("RunnableThread")) { | 313 | if (component.getComponentType().equals("RunnableThread")) { | |
| 314 | SingleLockState runState=map.get("run"); | 314 | SingleLockState runState=map.get("run"); | |
| 315 | if (locking(runState)) { | 315 | if (locking(runState)) { | |
| 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } | |
| 319 | if (component.getComponentType().equals("Handler")) { | 319 | if (component.getComponentType().equals("Handler")) { | |
| 320 | SingleLockState handleState=map.get("handleMessage"); | 320 | SingleLockState handleState=map.get("handleMessage"); | |
| 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 323 | } | 323 | } | |
| 324 | } | 324 | } | |
| 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 326 | SingleLockState onReceiveState=map.get("onReceive"); | 326 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 327 | if (locking(onReceiveState)) { | 327 | if (locking(onReceiveState)) { | |
| 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 329 | } | 329 | } | |
| 330 | } | 330 | } | |
| 331 | } | 331 | } | |
| 332 | } | 332 | } | |
| 333 | } | 333 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_074 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_075 | |||
|---|---|---|---|---|
|
333 lines 13408 bytes Last modified : Mon May 14 20:27:55 2012 |
333 lines 13414 bytes Last modified : Mon May 14 20:27:55 2012 |
|||
| 1 | //Time : 2012-04-26 20:49:44.084 | 1 | //Time : 2012-04-26 20:49:49.181 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | public class AnalysisResults { | 18 | public class AnalysisResults { | |
| 19 | /** | 19 | /** | |
| 20 | * Main structures that hold the analysis results for every component | 20 | * Main structures that hold the analysis results for every component | |
| 21 | */ | 21 | */ | |
| 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 23 | public class ComponentSummary { | 23 | public class ComponentSummary { | |
| 24 | private Component component; | 24 | private Component component; | |
| 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 27 | public ComponentSummary( Component c){ | 27 | public ComponentSummary( Component c){ | |
| 28 | this.component=c; | 28 | this.component=c; | |
| 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 31 | } | 31 | } | |
| 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 33 | return allExitStates; | 33 | return allExitStates; | |
| 34 | } | 34 | } | |
| 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 36 | allExitStates.put(n,st); | 36 | allExitStates.put(n,st); | |
| 37 | } | 37 | } | |
| 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 39 | callBackExitStates.put(cb,st); | 39 | callBackExitStates.put(cb,st); | |
| 40 | } | 40 | } | |
| 41 | public CompoundLockState getStateForMethod( String method){ | 41 | public CompoundLockState getStateForMethod( String method){ | |
| 42 | return allExitStates.get(method); | 42 | return allExitStates.get(method); | |
| 43 | } | 43 | } | |
| 44 | public String toString(){ | 44 | public String toString(){ | |
| 45 | StringBuffer sb=new StringBuffer(); | 45 | StringBuffer sb=new StringBuffer(); | |
| 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 47 | CGNode next=it.next(); | 47 | CGNode next=it.next(); | |
| 48 | String name=next.getMethod().getName().toString(); | 48 | String name=next.getMethod().getName().toString(); | |
| 49 | CompoundLockState stateForMethod=getStateForMethod(name); | 49 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 50 | if (stateForMethod != null) { | 50 | if (stateForMethod != null) { | |
| 51 | sb.append(name + ":\n" + stateForMethod.toString()); | 51 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 52 | } | 52 | } | |
| 53 | } | 53 | } | |
| 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 55 | if (callbacks != null) { | 55 | if (callbacks != null) { | |
| 56 | if (callbacks.size() > 0) { | 56 | if (callbacks.size() > 0) { | |
| 57 | sb.append("Callbacks:\n"); | 57 | sb.append("Callbacks:\n"); | |
| 58 | for ( CallBack cb : callbacks) { | 58 | for ( CallBack cb : callbacks) { | |
| 59 | String name=cb.getName(); | 59 | String name=cb.getName(); | |
| 60 | ; | 60 | ; | |
| 61 | CompoundLockState stateForMethod=getStateForMethod(name); | 61 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 62 | if (stateForMethod != null) { | 62 | if (stateForMethod != null) { | |
| 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 64 | } | 64 | } | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | return null; | 68 | return null; | |
| 69 | } | 69 | } | |
| 70 | } | 70 | } | |
| 71 | public AnalysisResults(){ | 71 | public AnalysisResults(){ | |
| 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 73 | } | 73 | } | |
| 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 76 | public static class Result { | 76 | public static class Result { | |
| 77 | private ResultType resultType; | 77 | private ResultType resultType; | |
| 78 | private String message; | 78 | private String message; | |
| 79 | public ResultType getResultType(){ | 79 | public ResultType getResultType(){ | |
| 80 | return resultType; | 80 | return resultType; | |
| 81 | } | 81 | } | |
| 82 | public String getMessage(){ | 82 | public String getMessage(){ | |
| 83 | return message; | 83 | return message; | |
| 84 | } | 84 | } | |
| 85 | public Result( ResultType rt, String msg){ | 85 | public Result( ResultType rt, String msg){ | |
| 86 | message=msg; | 86 | message=msg; | |
| 87 | resultType=rt; | 87 | resultType=rt; | |
| 88 | } | 88 | } | |
| 89 | public String toString(){ | 89 | public String toString(){ | |
| 90 | return (resultType.name() + " " + message); | 90 | return (resultType.name() + " " + message); | |
| 91 | } | 91 | } | |
| 92 | } | 92 | } | |
| 93 | /** | 93 | /** | |
| 94 | * Invoke this after the component has been analyzed | 94 | * Invoke this after the component has been analyzed | |
| 95 | * @param component | 95 | * @param component | |
| 96 | */ | 96 | */ | |
| 97 | public void createComponentSummary( Component component){ | 97 | public void createComponentSummary( Component component){ | |
| 98 | ComponentSummary componentSummary=new ComponentSummary(component); | 98 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 100 | CGNode next=it.next(); | 100 | CGNode next=it.next(); | |
| 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 102 | if (exitState != null) { | 102 | if (exitState != null) { | |
| 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 104 | componentSummary.registerNodeState(next,compoundLockState); | 104 | componentSummary.registerNodeState(next,compoundLockState); | |
| 105 | } | 105 | } | |
| 106 | } | 106 | } | |
| 107 | allStates.add(Pair.make(component,componentSummary)); | 107 | allStates.add(Pair.make(component,componentSummary)); | |
| 108 | } | 108 | } | |
| 109 | private LockUsage getLockUsage( SingleLockState runState){ | 109 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 110 | if (runState != null) { | 110 | if (runState != null) { | |
| 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 112 | return LockUsage.LOCKING; | 112 | return LockUsage.LOCKING; | |
| 113 | } | 113 | } | |
| 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 115 | return LockUsage.EMPTY; | 115 | return LockUsage.EMPTY; | |
| 116 | } | 116 | } | |
| 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 118 | return LockUsage.FULL_UNLOCKING; | 118 | return LockUsage.FULL_UNLOCKING; | |
| 119 | } | 119 | } | |
| 120 | else if (runState.isMaybeReleased()) { | 120 | else if (runState.isMaybeReleased()) { | |
| 121 | return LockUsage.UNLOCKING; | 121 | return LockUsage.UNLOCKING; | |
| 122 | } | 122 | } | |
| 123 | else { | 123 | else { | |
| 124 | return LockUsage.UNKNOWN_STATE; | 124 | return LockUsage.UNKNOWN_STATE; | |
| 125 | } | 125 | } | |
| 126 | } | 126 | } | |
| 127 | else { | 127 | else { | |
| 128 | return LockUsage.EMPTY; | 128 | return LockUsage.EMPTY; | |
| 129 | } | 129 | } | |
| 130 | } | 130 | } | |
| 131 | public ArrayList<Result> processResults(){ | 131 | public ArrayList<Result> processResults(){ | |
| 132 | ArrayList<Result> result=new ArrayList<Result>(); | 132 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 133 | System.out.println("\n=========================================="); | 133 | System.out.println("\n=========================================="); | |
| 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 137 | Component component=pair.fst; | 137 | Component component=pair.fst; | |
| 138 | ComponentSummary cSummary=pair.snd; | 138 | ComponentSummary cSummary=pair.snd; | |
| 139 | ComponentPolicy policy=new ComponentPolicy(component); | 139 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 140 | StringBuffer sb=new StringBuffer(); | 140 | StringBuffer sb=new StringBuffer(); | |
| 141 | boolean printComponent=false; | 141 | boolean printComponent=false; | |
| 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 143 | CGNode node=e.getKey(); | 143 | CGNode node=e.getKey(); | |
| 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 145 | boolean printMethod=false; | 145 | boolean printMethod=false; | |
| 146 | LockUsage lockUsage=LockUsage.EMPTY; | 146 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 147 | CompoundLockState compLS=e.getValue(); | 147 | CompoundLockState compLS=e.getValue(); | |
| 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 150 | WakeLockInstance wli=fs.getKey(); | 150 | WakeLockInstance wli=fs.getKey(); | |
| 151 | Set<SingleLockState> sls=fs.getValue(); | 151 | Set<SingleLockState> sls=fs.getValue(); | |
| 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 153 | lockUsage=getLockUsage(sl); | 153 | lockUsage=getLockUsage(sl); | |
| 154 | lockUsages.put(wli,lockUsage); | 154 | lockUsages.put(wli,lockUsage); | |
| 155 | if (lockUsage != LockUsage.EMPTY) { | 155 | if (lockUsage != LockUsage.EMPTY) { | |
| 156 | printMethod=true; | 156 | printMethod=true; | |
| 157 | } | 157 | } | |
| 158 | } | 158 | } | |
| 159 | if (printMethod) { | 159 | if (printMethod) { | |
| 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 161 | printComponent=true; | 161 | printComponent=true; | |
| 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 165 | WakeLockInstance key=fs.getKey(); | 165 | WakeLockInstance key=fs.getKey(); | |
| 166 | Set<SingleLockState> value=fs.getValue(); | 166 | Set<SingleLockState> value=fs.getValue(); | |
| 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 169 | } | 169 | } | |
| 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 171 | LockUsage lu=getLockUsage(mergedLS); | 171 | LockUsage lu=getLockUsage(mergedLS); | |
| 172 | if (component.isCallBack(node)) { | 172 | if (component.isCallBack(node)) { | |
| 173 | if (usageMap.containsKey(lu)) { | 173 | if (usageMap.containsKey(lu)) { | |
| 174 | usageMap.get(lu).add(Pair.make(component,node)); | 174 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 175 | } | 175 | } | |
| 176 | else { | 176 | else { | |
| 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 178 | set.add(Pair.make(component,node)); | 178 | set.add(Pair.make(component,node)); | |
| 179 | usageMap.put(lu,set); | 179 | usageMap.put(lu,set); | |
| 180 | } | 180 | } | |
| 181 | policy.addFact(node,mergedLS); | 181 | policy.addFact(node,mergedLS); | |
| 182 | } | 182 | } | |
| 183 | } | 183 | } | |
| 184 | } | 184 | } | |
| 185 | } | 185 | } | |
| 186 | if (printComponent) { | 186 | if (printComponent) { | |
| 187 | System.out.println(component.toString() + "\n" + sb.toString()); | 187 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 188 | policy.solveFacts(); | 188 | policy.solveFacts(); | |
| 189 | componentMap.put(component,policy.getLogger()); | 189 | componentMap.put(component,policy.getLogger()); | |
| 190 | } | 190 | } | |
| 191 | } | 191 | } | |
| 192 | System.out.println("==========================================\n"); | 192 | System.out.println("==========================================\n"); | |
| 193 | for ( LockUsage e : usageMap.keySet()) { | 193 | for ( LockUsage e : usageMap.keySet()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 196 | System.out.println(" " + s.toString()); | 196 | System.out.println(" " + s.toString()); | |
| 197 | } | 197 | } | |
| 198 | } | 198 | } | |
| 199 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 200 | for ( Component e : componentMap.keySet()) { | 200 | for ( Component e : componentMap.keySet()) { | |
| 201 | Logger logger=componentMap.get(e); | 201 | Logger logger=componentMap.get(e); | |
| 202 | if (!logger.isEmpty()) { | 202 | if (!logger.isEmpty()) { | |
| 203 | System.out.println(e.toString()); | 203 | System.out.println(e.toString()); | |
| 204 | System.out.println(logger.toString()); | 204 | System.out.println(logger.toString()); | |
| 205 | System.out.println("\n"); | 205 | System.out.println("\n"); | |
| 206 | } | 206 | } | |
| 207 | result=logger.getStringList(); | 207 | result=logger.getStringList(); | |
| 208 | } | 208 | } | |
| 209 | return result; | 209 | return result; | |
| 210 | } | 210 | } | |
| 211 | public class Logger extends ArrayList<Result> { | 211 | public class Logger extends ArrayList<Result> { | |
| 212 | private static final long serialVersionUID=4402714524487791090L; | 212 | private static final long serialVersionUID=4402714524487791090L; | |
| 213 | public void output(){ | 213 | public void output(){ | |
| 214 | for ( Result r : this) { | 214 | for ( Result r : this) { | |
| 215 | System.out.println(" " + r.getResultType().toString()); | 215 | System.out.println(" " + r.getResultType().toString()); | |
| 216 | } | 216 | } | |
| 217 | } | 217 | } | |
| 218 | public ArrayList<Result> getStringList(){ | 218 | public ArrayList<Result> getStringList(){ | |
| 219 | return this; | 219 | return this; | |
| 220 | } | 220 | } | |
| 221 | public String toString(){ | 221 | public String toString(){ | |
| 222 | StringBuffer result=new StringBuffer(); | 222 | StringBuffer result=new StringBuffer(); | |
| 223 | for ( Result r : this) { | 223 | for ( Result r : this) { | |
| 224 | result.append(r.toString() + "\n"); | 224 | result.append(r.toString() + "\n"); | |
| 225 | } | 225 | } | |
| 226 | return result.toString(); | 226 | return result.toString(); | |
| 227 | } | 227 | } | |
| 228 | } | 228 | } | |
| 229 | public class ComponentPolicy { | 229 | public class ComponentPolicy { | |
| 230 | private Component component; | 230 | private Component component; | |
| 231 | public ComponentPolicy( Component component){ | 231 | public ComponentPolicy( Component component){ | |
| 232 | this.component=component; | 232 | this.component=component; | |
| 233 | map=new HashMap<String,SingleLockState>(); | 233 | map=new HashMap<String,SingleLockState>(); | |
| 234 | logger=new Logger(); | 234 | logger=new Logger(); | |
| 235 | } | 235 | } | |
| 236 | private HashMap<String,SingleLockState> map; | 236 | private HashMap<String,SingleLockState> map; | |
| 237 | public void addFact( CGNode n, SingleLockState st){ | 237 | public void addFact( CGNode n, SingleLockState st){ | |
| 238 | map.put(n.getMethod().getName().toString(),st); | 238 | map.put(n.getMethod().getName().toString(),st); | |
| 239 | } | 239 | } | |
| 240 | private boolean unlocking( SingleLockState state){ | 240 | private boolean unlocking( SingleLockState state){ | |
| 241 | return (strongUnlocking(state) || weakUnlocking(state)); | 241 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 242 | } | 242 | } | |
| 243 | private boolean strongUnlocking( SingleLockState state){ | 243 | private boolean strongUnlocking( SingleLockState state){ | |
| 244 | if (state != null) { | 244 | if (state != null) { | |
| 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 246 | } | 246 | } | |
| 247 | return true; | 247 | return true; | |
| 248 | } | 248 | } | |
| 249 | private boolean weakUnlocking( SingleLockState state){ | 249 | private boolean weakUnlocking( SingleLockState state){ | |
| 250 | if (state != null) { | 250 | if (state != null) { | |
| 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 252 | } | 252 | } | |
| 253 | return true; | 253 | return true; | |
| 254 | } | 254 | } | |
| 255 | private boolean locking( SingleLockState onCreateState){ | 255 | private boolean locking( SingleLockState onCreateState){ | |
| 256 | if (onCreateState != null) { | 256 | if (onCreateState != null) { | |
| 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 258 | } | 258 | } | |
| 259 | return false; | 259 | return false; | |
| 260 | } | 260 | } | |
| 261 | private Logger logger; | 261 | private Logger logger; | |
| 262 | private void logNote( Result result){ | 262 | private void logNote( Result result){ | |
| 263 | logger.add(result); | 263 | logger.add(result); | |
| 264 | } | 264 | } | |
| 265 | public Logger getLogger(){ | 265 | public Logger getLogger(){ | |
| 266 | return logger; | 266 | return logger; | |
| 267 | } | 267 | } | |
| 268 | private SingleLockState getServiceOnStart(){ | 268 | private SingleLockState getServiceOnStart(){ | |
| 269 | SingleLockState onStart=map.get("onStart"); | 269 | SingleLockState onStart=map.get("onStart"); | |
| 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 271 | if (onStartCommand == null) { | 271 | if (onStartCommand == null) { | |
| 272 | return onStart; | 272 | return onStart; | |
| 273 | } | 273 | } | |
| 274 | else { | 274 | else { | |
| 275 | return onStartCommand; | 275 | return onStartCommand; | |
| 276 | } | 276 | } | |
| 277 | } | 277 | } | |
| 278 | /** | 278 | /** | |
| 279 | * TODO: make sure the same lock is locked and unlocked... | 279 | * TODO: make sure the same lock is locked and unlocked... | |
| 280 | */ | 280 | */ | |
| 281 | public void solveFacts(){ | 281 | public void solveFacts(){ | |
| 282 | if (component.getComponentType().equals("Activity")) { | 282 | if (component.getComponentType().equals("Activity")) { | |
| 283 | SingleLockState onCreateState=map.get("onCreate"); | 283 | SingleLockState onCreateState=map.get("onCreate"); | |
| 284 | if (locking(onCreateState)) { | 284 | if (locking(onCreateState)) { | |
| 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onStartState=map.get("onStart"); | 287 | SingleLockState onStartState=map.get("onStart"); | |
| 288 | if (locking(onStartState)) { | 288 | if (locking(onStartState)) { | |
| 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 290 | } | 290 | } | |
| 291 | SingleLockState onRestartState=map.get("onRestart"); | 291 | SingleLockState onRestartState=map.get("onRestart"); | |
| 292 | if (locking(onRestartState)) { | 292 | if (locking(onRestartState)) { | |
| 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 294 | } | 294 | } | |
| 295 | SingleLockState onPauseState=map.get("onPause"); | 295 | SingleLockState onPauseState=map.get("onPause"); | |
| 296 | if (!unlocking(onPauseState)) { | 296 | if (!unlocking(onPauseState)) { | |
| 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("Service")) { | 303 | if (component.getComponentType().equals("Service")) { | |
| 304 | SingleLockState onStartState=getServiceOnStart(); | 304 | SingleLockState onStartState=getServiceOnStart(); | |
| 305 | SingleLockState onDestroyState=map.get("onDestroy"); | 305 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | if (weakUnlocking(onDestroyState) && !strongUnlocking(onDestroyState)) { | 309 | if (weakUnlocking(onDestroyState) && (void)!strongUnlocking(onDestroyState)) { | |
| 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | if (component.getComponentType().equals("RunnableThread")) { | 313 | if (component.getComponentType().equals("RunnableThread")) { | |
| 314 | SingleLockState runState=map.get("run"); | 314 | SingleLockState runState=map.get("run"); | |
| 315 | if (locking(runState)) { | 315 | if (locking(runState)) { | |
| 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 317 | } | 317 | } | |
| 318 | } | 318 | } | |
| 319 | if (component.getComponentType().equals("Handler")) { | 319 | if (component.getComponentType().equals("Handler")) { | |
| 320 | SingleLockState handleState=map.get("handleMessage"); | 320 | SingleLockState handleState=map.get("handleMessage"); | |
| 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 323 | } | 323 | } | |
| 324 | } | 324 | } | |
| 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 326 | SingleLockState onReceiveState=map.get("onReceive"); | 326 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 327 | if (locking(onReceiveState)) { | 327 | if (locking(onReceiveState)) { | |
| 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 329 | } | 329 | } | |
| 330 | } | 330 | } | |
| 331 | } | 331 | } | |
| 332 | } | 332 | } | |
| 333 | } | 333 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_075 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_076 | |||
|---|---|---|---|---|
|
333 lines 13414 bytes Last modified : Mon May 14 20:27:55 2012 |
334 lines 13420 bytes Last modified : Mon May 14 20:27:55 2012 |
|||
| 1 | //Time : 2012-04-26 20:49:49.181 | 1 | //Time : 2012-04-26 20:49:57.004 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | public class AnalysisResults { | 18 | public class AnalysisResults { | |
| 19 | /** | 19 | /** | |
| 20 | * Main structures that hold the analysis results for every component | 20 | * Main structures that hold the analysis results for every component | |
| 21 | */ | 21 | */ | |
| 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 23 | public class ComponentSummary { | 23 | public class ComponentSummary { | |
| 24 | private Component component; | 24 | private Component component; | |
| 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 27 | public ComponentSummary( Component c){ | 27 | public ComponentSummary( Component c){ | |
| 28 | this.component=c; | 28 | this.component=c; | |
| 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 31 | } | 31 | } | |
| 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 33 | return allExitStates; | 33 | return allExitStates; | |
| 34 | } | 34 | } | |
| 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 36 | allExitStates.put(n,st); | 36 | allExitStates.put(n,st); | |
| 37 | } | 37 | } | |
| 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 39 | callBackExitStates.put(cb,st); | 39 | callBackExitStates.put(cb,st); | |
| 40 | } | 40 | } | |
| 41 | public CompoundLockState getStateForMethod( String method){ | 41 | public CompoundLockState getStateForMethod( String method){ | |
| 42 | return allExitStates.get(method); | 42 | return allExitStates.get(method); | |
| 43 | } | 43 | } | |
| 44 | public String toString(){ | 44 | public String toString(){ | |
| 45 | StringBuffer sb=new StringBuffer(); | 45 | StringBuffer sb=new StringBuffer(); | |
| 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 47 | CGNode next=it.next(); | 47 | CGNode next=it.next(); | |
| 48 | String name=next.getMethod().getName().toString(); | 48 | String name=next.getMethod().getName().toString(); | |
| 49 | CompoundLockState stateForMethod=getStateForMethod(name); | 49 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 50 | if (stateForMethod != null) { | 50 | if (stateForMethod != null) { | |
| 51 | sb.append(name + ":\n" + stateForMethod.toString()); | 51 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 52 | } | 52 | } | |
| 53 | } | 53 | } | |
| 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 55 | if (callbacks != null) { | 55 | if (callbacks != null) { | |
| 56 | if (callbacks.size() > 0) { | 56 | if (callbacks.size() > 0) { | |
| 57 | sb.append("Callbacks:\n"); | 57 | sb.append("Callbacks:\n"); | |
| 58 | for ( CallBack cb : callbacks) { | 58 | for ( CallBack cb : callbacks) { | |
| 59 | String name=cb.getName(); | 59 | String name=cb.getName(); | |
| 60 | ; | 60 | ; | |
| 61 | CompoundLockState stateForMethod=getStateForMethod(name); | 61 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 62 | if (stateForMethod != null) { | 62 | if (stateForMethod != null) { | |
| 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 64 | } | 64 | } | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | return null; | 68 | return null; | |
| 69 | } | 69 | } | |
| 70 | } | 70 | } | |
| 71 | public AnalysisResults(){ | 71 | public AnalysisResults(){ | |
| 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 73 | } | 73 | } | |
| 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 76 | public static class Result { | 76 | public static class Result { | |
| 77 | private ResultType resultType; | 77 | private ResultType resultType; | |
| 78 | private String message; | 78 | private String message; | |
| 79 | public ResultType getResultType(){ | 79 | public ResultType getResultType(){ | |
| 80 | return resultType; | 80 | return resultType; | |
| 81 | } | 81 | } | |
| 82 | public String getMessage(){ | 82 | public String getMessage(){ | |
| 83 | return message; | 83 | return message; | |
| 84 | } | 84 | } | |
| 85 | public Result( ResultType rt, String msg){ | 85 | public Result( ResultType rt, String msg){ | |
| 86 | message=msg; | 86 | message=msg; | |
| 87 | resultType=rt; | 87 | resultType=rt; | |
| 88 | } | 88 | } | |
| 89 | public String toString(){ | 89 | public String toString(){ | |
| 90 | return (resultType.name() + " " + message); | 90 | return (resultType.name() + " " + message); | |
| 91 | } | 91 | } | |
| 92 | } | 92 | } | |
| 93 | /** | 93 | /** | |
| 94 | * Invoke this after the component has been analyzed | 94 | * Invoke this after the component has been analyzed | |
| 95 | * @param component | 95 | * @param component | |
| 96 | */ | 96 | */ | |
| 97 | public void createComponentSummary( Component component){ | 97 | public void createComponentSummary( Component component){ | |
| 98 | ComponentSummary componentSummary=new ComponentSummary(component); | 98 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 100 | CGNode next=it.next(); | 100 | CGNode next=it.next(); | |
| 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 102 | if (exitState != null) { | 102 | if (exitState != null) { | |
| 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 104 | componentSummary.registerNodeState(next,compoundLockState); | 104 | componentSummary.registerNodeState(next,compoundLockState); | |
| 105 | } | 105 | } | |
| 106 | } | 106 | } | |
| 107 | allStates.add(Pair.make(component,componentSummary)); | 107 | allStates.add(Pair.make(component,componentSummary)); | |
| 108 | } | 108 | } | |
| 109 | private LockUsage getLockUsage( SingleLockState runState){ | 109 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 110 | if (runState != null) { | 110 | if (runState != null) { | |
| 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 112 | return LockUsage.LOCKING; | 112 | return LockUsage.LOCKING; | |
| 113 | } | 113 | } | |
| 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 115 | return LockUsage.EMPTY; | 115 | return LockUsage.EMPTY; | |
| 116 | } | 116 | } | |
| 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 118 | return LockUsage.FULL_UNLOCKING; | 118 | return LockUsage.FULL_UNLOCKING; | |
| 119 | } | 119 | } | |
| 120 | else if (runState.isMaybeReleased()) { | 120 | else if (runState.isMaybeReleased()) { | |
| 121 | return LockUsage.UNLOCKING; | 121 | return LockUsage.UNLOCKING; | |
| 122 | } | 122 | } | |
| 123 | else { | 123 | else { | |
| 124 | return LockUsage.UNKNOWN_STATE; | 124 | return LockUsage.UNKNOWN_STATE; | |
| 125 | } | 125 | } | |
| 126 | } | 126 | } | |
| 127 | else { | 127 | else { | |
| 128 | return LockUsage.EMPTY; | 128 | return LockUsage.EMPTY; | |
| 129 | } | 129 | } | |
| 130 | } | 130 | } | |
| 131 | public ArrayList<Result> processResults(){ | 131 | public ArrayList<Result> processResults(){ | |
| 132 | ArrayList<Result> result=new ArrayList<Result>(); | 132 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 133 | System.out.println("\n=========================================="); | 133 | System.out.println("\n=========================================="); | |
| 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 137 | Component component=pair.fst; | 137 | Component component=pair.fst; | |
| 138 | ComponentSummary cSummary=pair.snd; | 138 | ComponentSummary cSummary=pair.snd; | |
| 139 | ComponentPolicy policy=new ComponentPolicy(component); | 139 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 140 | StringBuffer sb=new StringBuffer(); | 140 | StringBuffer sb=new StringBuffer(); | |
| 141 | boolean printComponent=false; | 141 | boolean printComponent=false; | |
| 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 143 | CGNode node=e.getKey(); | 143 | CGNode node=e.getKey(); | |
| 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 145 | boolean printMethod=false; | 145 | boolean printMethod=false; | |
| 146 | LockUsage lockUsage=LockUsage.EMPTY; | 146 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 147 | CompoundLockState compLS=e.getValue(); | 147 | CompoundLockState compLS=e.getValue(); | |
| 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 150 | WakeLockInstance wli=fs.getKey(); | 150 | WakeLockInstance wli=fs.getKey(); | |
| 151 | Set<SingleLockState> sls=fs.getValue(); | 151 | Set<SingleLockState> sls=fs.getValue(); | |
| 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 153 | lockUsage=getLockUsage(sl); | 153 | lockUsage=getLockUsage(sl); | |
| 154 | lockUsages.put(wli,lockUsage); | 154 | lockUsages.put(wli,lockUsage); | |
| 155 | if (lockUsage != LockUsage.EMPTY) { | 155 | if (lockUsage != LockUsage.EMPTY) { | |
| 156 | printMethod=true; | 156 | printMethod=true; | |
| 157 | } | 157 | } | |
| 158 | } | 158 | } | |
| 159 | if (printMethod) { | 159 | if (printMethod) { | |
| 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 161 | printComponent=true; | 161 | printComponent=true; | |
| 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 165 | WakeLockInstance key=fs.getKey(); | 165 | WakeLockInstance key=fs.getKey(); | |
| 166 | Set<SingleLockState> value=fs.getValue(); | 166 | Set<SingleLockState> value=fs.getValue(); | |
| 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 169 | } | 169 | } | |
| 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 171 | LockUsage lu=getLockUsage(mergedLS); | 171 | LockUsage lu=getLockUsage(mergedLS); | |
| 172 | if (component.isCallBack(node)) { | 172 | if (component.isCallBack(node)) { | |
| 173 | if (usageMap.containsKey(lu)) { | 173 | if (usageMap.containsKey(lu)) { | |
| 174 | usageMap.get(lu).add(Pair.make(component,node)); | 174 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 175 | } | 175 | } | |
| 176 | else { | 176 | else { | |
| 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 178 | set.add(Pair.make(component,node)); | 178 | set.add(Pair.make(component,node)); | |
| 179 | usageMap.put(lu,set); | 179 | usageMap.put(lu,set); | |
| 180 | } | 180 | } | |
| 181 | policy.addFact(node,mergedLS); | 181 | policy.addFact(node,mergedLS); | |
| 182 | } | 182 | } | |
| 183 | } | 183 | } | |
| 184 | } | 184 | } | |
| 185 | } | 185 | } | |
| 186 | if (printComponent) { | 186 | if (printComponent) { | |
| 187 | System.out.println(component.toString() + "\n" + sb.toString()); | 187 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 188 | policy.solveFacts(); | 188 | policy.solveFacts(); | |
| 189 | componentMap.put(component,policy.getLogger()); | 189 | componentMap.put(component,policy.getLogger()); | |
| 190 | } | 190 | } | |
| 191 | } | 191 | } | |
| 192 | System.out.println("==========================================\n"); | 192 | System.out.println("==========================================\n"); | |
| 193 | for ( LockUsage e : usageMap.keySet()) { | 193 | for ( LockUsage e : usageMap.keySet()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 196 | System.out.println(" " + s.toString()); | 196 | System.out.println(" " + s.toString()); | |
| 197 | } | 197 | } | |
| 198 | } | 198 | } | |
| 199 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 200 | for ( Component e : componentMap.keySet()) { | 200 | for ( Component e : componentMap.keySet()) { | |
| 201 | Logger logger=componentMap.get(e); | 201 | Logger logger=componentMap.get(e); | |
| 202 | if (!logger.isEmpty()) { | 202 | if (!logger.isEmpty()) { | |
| 203 | System.out.println(e.toString()); | 203 | System.out.println(e.toString()); | |
| 204 | System.out.println(logger.toString()); | 204 | System.out.println(logger.toString()); | |
| 205 | System.out.println("\n"); | 205 | System.out.println("\n"); | |
| 206 | } | 206 | } | |
| 207 | result=logger.getStringList(); | 207 | result=logger.getStringList(); | |
| 208 | } | 208 | } | |
| 209 | return result; | 209 | return result; | |
| 210 | } | 210 | } | |
| 211 | public class Logger extends ArrayList<Result> { | 211 | public class Logger extends ArrayList<Result> { | |
| 212 | private static final long serialVersionUID=4402714524487791090L; | 212 | private static final long serialVersionUID=4402714524487791090L; | |
| 213 | public void output(){ | 213 | public void output(){ | |
| 214 | for ( Result r : this) { | 214 | for ( Result r : this) { | |
| 215 | System.out.println(" " + r.getResultType().toString()); | 215 | System.out.println(" " + r.getResultType().toString()); | |
| 216 | } | 216 | } | |
| 217 | } | 217 | } | |
| 218 | public ArrayList<Result> getStringList(){ | 218 | public ArrayList<Result> getStringList(){ | |
| 219 | return this; | 219 | return this; | |
| 220 | } | 220 | } | |
| 221 | public String toString(){ | 221 | public String toString(){ | |
| 222 | StringBuffer result=new StringBuffer(); | 222 | StringBuffer result=new StringBuffer(); | |
| 223 | for ( Result r : this) { | 223 | for ( Result r : this) { | |
| 224 | result.append(r.toString() + "\n"); | 224 | result.append(r.toString() + "\n"); | |
| 225 | } | 225 | } | |
| 226 | return result.toString(); | 226 | return result.toString(); | |
| 227 | } | 227 | } | |
| 228 | } | 228 | } | |
| 229 | public class ComponentPolicy { | 229 | public class ComponentPolicy { | |
| 230 | private Component component; | 230 | private Component component; | |
| 231 | public ComponentPolicy( Component component){ | 231 | public ComponentPolicy( Component component){ | |
| 232 | this.component=component; | 232 | this.component=component; | |
| 233 | map=new HashMap<String,SingleLockState>(); | 233 | map=new HashMap<String,SingleLockState>(); | |
| 234 | logger=new Logger(); | 234 | logger=new Logger(); | |
| 235 | } | 235 | } | |
| 236 | private HashMap<String,SingleLockState> map; | 236 | private HashMap<String,SingleLockState> map; | |
| 237 | public void addFact( CGNode n, SingleLockState st){ | 237 | public void addFact( CGNode n, SingleLockState st){ | |
| 238 | map.put(n.getMethod().getName().toString(),st); | 238 | map.put(n.getMethod().getName().toString(),st); | |
| 239 | } | 239 | } | |
| 240 | private boolean unlocking( SingleLockState state){ | 240 | private boolean unlocking( SingleLockState state){ | |
| 241 | return (strongUnlocking(state) || weakUnlocking(state)); | 241 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 242 | } | 242 | } | |
| 243 | private boolean strongUnlocking( SingleLockState state){ | 243 | private boolean strongUnlocking( SingleLockState state){ | |
| 244 | if (state != null) { | 244 | if (state != null) { | |
| 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 246 | } | 246 | } | |
| 247 | return true; | 247 | return true; | |
| 248 | } | 248 | } | |
| 249 | private boolean weakUnlocking( SingleLockState state){ | 249 | private boolean weakUnlocking( SingleLockState state){ | |
| 250 | if (state != null) { | 250 | if (state != null) { | |
| 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 252 | } | 252 | } | |
| 253 | return true; | 253 | return true; | |
| 254 | } | 254 | } | |
| 255 | private boolean locking( SingleLockState onCreateState){ | 255 | private boolean locking( SingleLockState onCreateState){ | |
| 256 | if (onCreateState != null) { | 256 | if (onCreateState != null) { | |
| 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 258 | } | 258 | } | |
| 259 | return false; | 259 | return false; | |
| 260 | } | 260 | } | |
| 261 | private Logger logger; | 261 | private Logger logger; | |
| 262 | private void logNote( Result result){ | 262 | private void logNote( Result result){ | |
| 263 | logger.add(result); | 263 | logger.add(result); | |
| 264 | } | 264 | } | |
| 265 | public Logger getLogger(){ | 265 | public Logger getLogger(){ | |
| 266 | return logger; | 266 | return logger; | |
| 267 | } | 267 | } | |
| 268 | private SingleLockState getServiceOnStart(){ | 268 | private SingleLockState getServiceOnStart(){ | |
| 269 | SingleLockState onStart=map.get("onStart"); | 269 | SingleLockState onStart=map.get("onStart"); | |
| 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 271 | if (onStartCommand == null) { | 271 | if (onStartCommand == null) { | |
| 272 | return onStart; | 272 | return onStart; | |
| 273 | } | 273 | } | |
| 274 | else { | 274 | else { | |
| 275 | return onStartCommand; | 275 | return onStartCommand; | |
| 276 | } | 276 | } | |
| 277 | } | 277 | } | |
| 278 | /** | 278 | /** | |
| 279 | * TODO: make sure the same lock is locked and unlocked... | 279 | * TODO: make sure the same lock is locked and unlocked... | |
| 280 | */ | 280 | */ | |
| 281 | public void solveFacts(){ | 281 | public void solveFacts(){ | |
| 282 | if (component.getComponentType().equals("Activity")) { | 282 | if (component.getComponentType().equals("Activity")) { | |
| 283 | SingleLockState onCreateState=map.get("onCreate"); | 283 | SingleLockState onCreateState=map.get("onCreate"); | |
| 284 | if (locking(onCreateState)) { | 284 | if (locking(onCreateState)) { | |
| 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onStartState=map.get("onStart"); | 287 | SingleLockState onStartState=map.get("onStart"); | |
| 288 | if (locking(onStartState)) { | 288 | if (locking(onStartState)) { | |
| 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 290 | } | 290 | } | |
| 291 | SingleLockState onRestartState=map.get("onRestart"); | 291 | SingleLockState onRestartState=map.get("onRestart"); | |
| 292 | if (locking(onRestartState)) { | 292 | if (locking(onRestartState)) { | |
| 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 294 | } | 294 | } | |
| 295 | SingleLockState onPauseState=map.get("onPause"); | 295 | SingleLockState onPauseState=map.get("onPause"); | |
| 296 | if (!unlocking(onPauseState)) { | 296 | if (!unlocking(onPauseState)) { | |
| 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("Service")) { | 303 | if (component.getComponentType().equals("Service")) { | |
| 304 | SingleLockState onStartState=getServiceOnStart(); | 304 | SingleLockState onStartState=getServiceOnStart(); | |
| 305 | SingleLockState onDestroyState=map.get("onDestroy"); | 305 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | if (weakUnlocking(onDestroyState) && (void)!strongUnlocking(onDestroyState)) { | 309 | if (weakUnlocking(onDestroyState) && (!strongUnlocking(onDestroyState))) ; | |
| 310 | { | |||
| 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 311 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 311 | } | 312 | } | |
| 312 | } | 313 | } | |
| 313 | if (component.getComponentType().equals("RunnableThread")) { | 314 | if (component.getComponentType().equals("RunnableThread")) { | |
| 314 | SingleLockState runState=map.get("run"); | 315 | SingleLockState runState=map.get("run"); | |
| 315 | if (locking(runState)) { | 316 | if (locking(runState)) { | |
| 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 317 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 317 | } | 318 | } | |
| 318 | } | 319 | } | |
| 319 | if (component.getComponentType().equals("Handler")) { | 320 | if (component.getComponentType().equals("Handler")) { | |
| 320 | SingleLockState handleState=map.get("handleMessage"); | 321 | SingleLockState handleState=map.get("handleMessage"); | |
| 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 322 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 323 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 323 | } | 324 | } | |
| 324 | } | 325 | } | |
| 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | 326 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 326 | SingleLockState onReceiveState=map.get("onReceive"); | 327 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 327 | if (locking(onReceiveState)) { | 328 | if (locking(onReceiveState)) { | |
| 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 329 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 329 | } | 330 | } | |
| 330 | } | 331 | } | |
| 331 | } | 332 | } | |
| 332 | } | 333 | } | |
| 333 | } | 334 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_076 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_077 | |||
|---|---|---|---|---|
|
334 lines 13420 bytes Last modified : Mon May 14 20:27:55 2012 |
333 lines 13410 bytes Last modified : Mon May 14 20:27:55 2012 |
|||
| 1 | //Time : 2012-04-26 20:49:57.004 | 1 | //Time : 2012-04-26 20:49:58.294 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | package energy.analysis; | |
| 4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 8 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 10 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 18 | public class AnalysisResults { | 18 | public class AnalysisResults { | |
| 19 | /** | 19 | /** | |
| 20 | * Main structures that hold the analysis results for every component | 20 | * Main structures that hold the analysis results for every component | |
| 21 | */ | 21 | */ | |
| 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 23 | public class ComponentSummary { | 23 | public class ComponentSummary { | |
| 24 | private Component component; | 24 | private Component component; | |
| 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 27 | public ComponentSummary( Component c){ | 27 | public ComponentSummary( Component c){ | |
| 28 | this.component=c; | 28 | this.component=c; | |
| 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 31 | } | 31 | } | |
| 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 33 | return allExitStates; | 33 | return allExitStates; | |
| 34 | } | 34 | } | |
| 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 36 | allExitStates.put(n,st); | 36 | allExitStates.put(n,st); | |
| 37 | } | 37 | } | |
| 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 39 | callBackExitStates.put(cb,st); | 39 | callBackExitStates.put(cb,st); | |
| 40 | } | 40 | } | |
| 41 | public CompoundLockState getStateForMethod( String method){ | 41 | public CompoundLockState getStateForMethod( String method){ | |
| 42 | return allExitStates.get(method); | 42 | return allExitStates.get(method); | |
| 43 | } | 43 | } | |
| 44 | public String toString(){ | 44 | public String toString(){ | |
| 45 | StringBuffer sb=new StringBuffer(); | 45 | StringBuffer sb=new StringBuffer(); | |
| 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 47 | CGNode next=it.next(); | 47 | CGNode next=it.next(); | |
| 48 | String name=next.getMethod().getName().toString(); | 48 | String name=next.getMethod().getName().toString(); | |
| 49 | CompoundLockState stateForMethod=getStateForMethod(name); | 49 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 50 | if (stateForMethod != null) { | 50 | if (stateForMethod != null) { | |
| 51 | sb.append(name + ":\n" + stateForMethod.toString()); | 51 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 52 | } | 52 | } | |
| 53 | } | 53 | } | |
| 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 55 | if (callbacks != null) { | 55 | if (callbacks != null) { | |
| 56 | if (callbacks.size() > 0) { | 56 | if (callbacks.size() > 0) { | |
| 57 | sb.append("Callbacks:\n"); | 57 | sb.append("Callbacks:\n"); | |
| 58 | for ( CallBack cb : callbacks) { | 58 | for ( CallBack cb : callbacks) { | |
| 59 | String name=cb.getName(); | 59 | String name=cb.getName(); | |
| 60 | ; | 60 | ; | |
| 61 | CompoundLockState stateForMethod=getStateForMethod(name); | 61 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 62 | if (stateForMethod != null) { | 62 | if (stateForMethod != null) { | |
| 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 64 | } | 64 | } | |
| 65 | } | 65 | } | |
| 66 | } | 66 | } | |
| 67 | } | 67 | } | |
| 68 | return null; | 68 | return null; | |
| 69 | } | 69 | } | |
| 70 | } | 70 | } | |
| 71 | public AnalysisResults(){ | 71 | public AnalysisResults(){ | |
| 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 73 | } | 73 | } | |
| 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 76 | public static class Result { | 76 | public static class Result { | |
| 77 | private ResultType resultType; | 77 | private ResultType resultType; | |
| 78 | private String message; | 78 | private String message; | |
| 79 | public ResultType getResultType(){ | 79 | public ResultType getResultType(){ | |
| 80 | return resultType; | 80 | return resultType; | |
| 81 | } | 81 | } | |
| 82 | public String getMessage(){ | 82 | public String getMessage(){ | |
| 83 | return message; | 83 | return message; | |
| 84 | } | 84 | } | |
| 85 | public Result( ResultType rt, String msg){ | 85 | public Result( ResultType rt, String msg){ | |
| 86 | message=msg; | 86 | message=msg; | |
| 87 | resultType=rt; | 87 | resultType=rt; | |
| 88 | } | 88 | } | |
| 89 | public String toString(){ | 89 | public String toString(){ | |
| 90 | return (resultType.name() + " " + message); | 90 | return (resultType.name() + " " + message); | |
| 91 | } | 91 | } | |
| 92 | } | 92 | } | |
| 93 | /** | 93 | /** | |
| 94 | * Invoke this after the component has been analyzed | 94 | * Invoke this after the component has been analyzed | |
| 95 | * @param component | 95 | * @param component | |
| 96 | */ | 96 | */ | |
| 97 | public void createComponentSummary( Component component){ | 97 | public void createComponentSummary( Component component){ | |
| 98 | ComponentSummary componentSummary=new ComponentSummary(component); | 98 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 100 | CGNode next=it.next(); | 100 | CGNode next=it.next(); | |
| 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 102 | if (exitState != null) { | 102 | if (exitState != null) { | |
| 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 104 | componentSummary.registerNodeState(next,compoundLockState); | 104 | componentSummary.registerNodeState(next,compoundLockState); | |
| 105 | } | 105 | } | |
| 106 | } | 106 | } | |
| 107 | allStates.add(Pair.make(component,componentSummary)); | 107 | allStates.add(Pair.make(component,componentSummary)); | |
| 108 | } | 108 | } | |
| 109 | private LockUsage getLockUsage( SingleLockState runState){ | 109 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 110 | if (runState != null) { | 110 | if (runState != null) { | |
| 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 112 | return LockUsage.LOCKING; | 112 | return LockUsage.LOCKING; | |
| 113 | } | 113 | } | |
| 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 115 | return LockUsage.EMPTY; | 115 | return LockUsage.EMPTY; | |
| 116 | } | 116 | } | |
| 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 118 | return LockUsage.FULL_UNLOCKING; | 118 | return LockUsage.FULL_UNLOCKING; | |
| 119 | } | 119 | } | |
| 120 | else if (runState.isMaybeReleased()) { | 120 | else if (runState.isMaybeReleased()) { | |
| 121 | return LockUsage.UNLOCKING; | 121 | return LockUsage.UNLOCKING; | |
| 122 | } | 122 | } | |
| 123 | else { | 123 | else { | |
| 124 | return LockUsage.UNKNOWN_STATE; | 124 | return LockUsage.UNKNOWN_STATE; | |
| 125 | } | 125 | } | |
| 126 | } | 126 | } | |
| 127 | else { | 127 | else { | |
| 128 | return LockUsage.EMPTY; | 128 | return LockUsage.EMPTY; | |
| 129 | } | 129 | } | |
| 130 | } | 130 | } | |
| 131 | public ArrayList<Result> processResults(){ | 131 | public ArrayList<Result> processResults(){ | |
| 132 | ArrayList<Result> result=new ArrayList<Result>(); | 132 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 133 | System.out.println("\n=========================================="); | 133 | System.out.println("\n=========================================="); | |
| 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 137 | Component component=pair.fst; | 137 | Component component=pair.fst; | |
| 138 | ComponentSummary cSummary=pair.snd; | 138 | ComponentSummary cSummary=pair.snd; | |
| 139 | ComponentPolicy policy=new ComponentPolicy(component); | 139 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 140 | StringBuffer sb=new StringBuffer(); | 140 | StringBuffer sb=new StringBuffer(); | |
| 141 | boolean printComponent=false; | 141 | boolean printComponent=false; | |
| 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 143 | CGNode node=e.getKey(); | 143 | CGNode node=e.getKey(); | |
| 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 145 | boolean printMethod=false; | 145 | boolean printMethod=false; | |
| 146 | LockUsage lockUsage=LockUsage.EMPTY; | 146 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 147 | CompoundLockState compLS=e.getValue(); | 147 | CompoundLockState compLS=e.getValue(); | |
| 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 150 | WakeLockInstance wli=fs.getKey(); | 150 | WakeLockInstance wli=fs.getKey(); | |
| 151 | Set<SingleLockState> sls=fs.getValue(); | 151 | Set<SingleLockState> sls=fs.getValue(); | |
| 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 153 | lockUsage=getLockUsage(sl); | 153 | lockUsage=getLockUsage(sl); | |
| 154 | lockUsages.put(wli,lockUsage); | 154 | lockUsages.put(wli,lockUsage); | |
| 155 | if (lockUsage != LockUsage.EMPTY) { | 155 | if (lockUsage != LockUsage.EMPTY) { | |
| 156 | printMethod=true; | 156 | printMethod=true; | |
| 157 | } | 157 | } | |
| 158 | } | 158 | } | |
| 159 | if (printMethod) { | 159 | if (printMethod) { | |
| 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 161 | printComponent=true; | 161 | printComponent=true; | |
| 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 165 | WakeLockInstance key=fs.getKey(); | 165 | WakeLockInstance key=fs.getKey(); | |
| 166 | Set<SingleLockState> value=fs.getValue(); | 166 | Set<SingleLockState> value=fs.getValue(); | |
| 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 169 | } | 169 | } | |
| 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 171 | LockUsage lu=getLockUsage(mergedLS); | 171 | LockUsage lu=getLockUsage(mergedLS); | |
| 172 | if (component.isCallBack(node)) { | 172 | if (component.isCallBack(node)) { | |
| 173 | if (usageMap.containsKey(lu)) { | 173 | if (usageMap.containsKey(lu)) { | |
| 174 | usageMap.get(lu).add(Pair.make(component,node)); | 174 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 175 | } | 175 | } | |
| 176 | else { | 176 | else { | |
| 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 178 | set.add(Pair.make(component,node)); | 178 | set.add(Pair.make(component,node)); | |
| 179 | usageMap.put(lu,set); | 179 | usageMap.put(lu,set); | |
| 180 | } | 180 | } | |
| 181 | policy.addFact(node,mergedLS); | 181 | policy.addFact(node,mergedLS); | |
| 182 | } | 182 | } | |
| 183 | } | 183 | } | |
| 184 | } | 184 | } | |
| 185 | } | 185 | } | |
| 186 | if (printComponent) { | 186 | if (printComponent) { | |
| 187 | System.out.println(component.toString() + "\n" + sb.toString()); | 187 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 188 | policy.solveFacts(); | 188 | policy.solveFacts(); | |
| 189 | componentMap.put(component,policy.getLogger()); | 189 | componentMap.put(component,policy.getLogger()); | |
| 190 | } | 190 | } | |
| 191 | } | 191 | } | |
| 192 | System.out.println("==========================================\n"); | 192 | System.out.println("==========================================\n"); | |
| 193 | for ( LockUsage e : usageMap.keySet()) { | 193 | for ( LockUsage e : usageMap.keySet()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 196 | System.out.println(" " + s.toString()); | 196 | System.out.println(" " + s.toString()); | |
| 197 | } | 197 | } | |
| 198 | } | 198 | } | |
| 199 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 200 | for ( Component e : componentMap.keySet()) { | 200 | for ( Component e : componentMap.keySet()) { | |
| 201 | Logger logger=componentMap.get(e); | 201 | Logger logger=componentMap.get(e); | |
| 202 | if (!logger.isEmpty()) { | 202 | if (!logger.isEmpty()) { | |
| 203 | System.out.println(e.toString()); | 203 | System.out.println(e.toString()); | |
| 204 | System.out.println(logger.toString()); | 204 | System.out.println(logger.toString()); | |
| 205 | System.out.println("\n"); | 205 | System.out.println("\n"); | |
| 206 | } | 206 | } | |
| 207 | result=logger.getStringList(); | 207 | result=logger.getStringList(); | |
| 208 | } | 208 | } | |
| 209 | return result; | 209 | return result; | |
| 210 | } | 210 | } | |
| 211 | public class Logger extends ArrayList<Result> { | 211 | public class Logger extends ArrayList<Result> { | |
| 212 | private static final long serialVersionUID=4402714524487791090L; | 212 | private static final long serialVersionUID=4402714524487791090L; | |
| 213 | public void output(){ | 213 | public void output(){ | |
| 214 | for ( Result r : this) { | 214 | for ( Result r : this) { | |
| 215 | System.out.println(" " + r.getResultType().toString()); | 215 | System.out.println(" " + r.getResultType().toString()); | |
| 216 | } | 216 | } | |
| 217 | } | 217 | } | |
| 218 | public ArrayList<Result> getStringList(){ | 218 | public ArrayList<Result> getStringList(){ | |
| 219 | return this; | 219 | return this; | |
| 220 | } | 220 | } | |
| 221 | public String toString(){ | 221 | public String toString(){ | |
| 222 | StringBuffer result=new StringBuffer(); | 222 | StringBuffer result=new StringBuffer(); | |
| 223 | for ( Result r : this) { | 223 | for ( Result r : this) { | |
| 224 | result.append(r.toString() + "\n"); | 224 | result.append(r.toString() + "\n"); | |
| 225 | } | 225 | } | |
| 226 | return result.toString(); | 226 | return result.toString(); | |
| 227 | } | 227 | } | |
| 228 | } | 228 | } | |
| 229 | public class ComponentPolicy { | 229 | public class ComponentPolicy { | |
| 230 | private Component component; | 230 | private Component component; | |
| 231 | public ComponentPolicy( Component component){ | 231 | public ComponentPolicy( Component component){ | |
| 232 | this.component=component; | 232 | this.component=component; | |
| 233 | map=new HashMap<String,SingleLockState>(); | 233 | map=new HashMap<String,SingleLockState>(); | |
| 234 | logger=new Logger(); | 234 | logger=new Logger(); | |
| 235 | } | 235 | } | |
| 236 | private HashMap<String,SingleLockState> map; | 236 | private HashMap<String,SingleLockState> map; | |
| 237 | public void addFact( CGNode n, SingleLockState st){ | 237 | public void addFact( CGNode n, SingleLockState st){ | |
| 238 | map.put(n.getMethod().getName().toString(),st); | 238 | map.put(n.getMethod().getName().toString(),st); | |
| 239 | } | 239 | } | |
| 240 | private boolean unlocking( SingleLockState state){ | 240 | private boolean unlocking( SingleLockState state){ | |
| 241 | return (strongUnlocking(state) || weakUnlocking(state)); | 241 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 242 | } | 242 | } | |
| 243 | private boolean strongUnlocking( SingleLockState state){ | 243 | private boolean strongUnlocking( SingleLockState state){ | |
| 244 | if (state != null) { | 244 | if (state != null) { | |
| 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 246 | } | 246 | } | |
| 247 | return true; | 247 | return true; | |
| 248 | } | 248 | } | |
| 249 | private boolean weakUnlocking( SingleLockState state){ | 249 | private boolean weakUnlocking( SingleLockState state){ | |
| 250 | if (state != null) { | 250 | if (state != null) { | |
| 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 252 | } | 252 | } | |
| 253 | return true; | 253 | return true; | |
| 254 | } | 254 | } | |
| 255 | private boolean locking( SingleLockState onCreateState){ | 255 | private boolean locking( SingleLockState onCreateState){ | |
| 256 | if (onCreateState != null) { | 256 | if (onCreateState != null) { | |
| 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 258 | } | 258 | } | |
| 259 | return false; | 259 | return false; | |
| 260 | } | 260 | } | |
| 261 | private Logger logger; | 261 | private Logger logger; | |
| 262 | private void logNote( Result result){ | 262 | private void logNote( Result result){ | |
| 263 | logger.add(result); | 263 | logger.add(result); | |
| 264 | } | 264 | } | |
| 265 | public Logger getLogger(){ | 265 | public Logger getLogger(){ | |
| 266 | return logger; | 266 | return logger; | |
| 267 | } | 267 | } | |
| 268 | private SingleLockState getServiceOnStart(){ | 268 | private SingleLockState getServiceOnStart(){ | |
| 269 | SingleLockState onStart=map.get("onStart"); | 269 | SingleLockState onStart=map.get("onStart"); | |
| 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 271 | if (onStartCommand == null) { | 271 | if (onStartCommand == null) { | |
| 272 | return onStart; | 272 | return onStart; | |
| 273 | } | 273 | } | |
| 274 | else { | 274 | else { | |
| 275 | return onStartCommand; | 275 | return onStartCommand; | |
| 276 | } | 276 | } | |
| 277 | } | 277 | } | |
| 278 | /** | 278 | /** | |
| 279 | * TODO: make sure the same lock is locked and unlocked... | 279 | * TODO: make sure the same lock is locked and unlocked... | |
| 280 | */ | 280 | */ | |
| 281 | public void solveFacts(){ | 281 | public void solveFacts(){ | |
| 282 | if (component.getComponentType().equals("Activity")) { | 282 | if (component.getComponentType().equals("Activity")) { | |
| 283 | SingleLockState onCreateState=map.get("onCreate"); | 283 | SingleLockState onCreateState=map.get("onCreate"); | |
| 284 | if (locking(onCreateState)) { | 284 | if (locking(onCreateState)) { | |
| 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onStartState=map.get("onStart"); | 287 | SingleLockState onStartState=map.get("onStart"); | |
| 288 | if (locking(onStartState)) { | 288 | if (locking(onStartState)) { | |
| 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 290 | } | 290 | } | |
| 291 | SingleLockState onRestartState=map.get("onRestart"); | 291 | SingleLockState onRestartState=map.get("onRestart"); | |
| 292 | if (locking(onRestartState)) { | 292 | if (locking(onRestartState)) { | |
| 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 294 | } | 294 | } | |
| 295 | SingleLockState onPauseState=map.get("onPause"); | 295 | SingleLockState onPauseState=map.get("onPause"); | |
| 296 | if (!unlocking(onPauseState)) { | 296 | if (!unlocking(onPauseState)) { | |
| 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("Service")) { | 303 | if (component.getComponentType().equals("Service")) { | |
| 304 | SingleLockState onStartState=getServiceOnStart(); | 304 | SingleLockState onStartState=getServiceOnStart(); | |
| 305 | SingleLockState onDestroyState=map.get("onDestroy"); | 305 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | if (weakUnlocking(onDestroyState) && (!strongUnlocking(onDestroyState))) ; | 309 | if (weakUnlocking(onDestroyState) && (!strongUnlocking(onDestroyState))) { | |
| 310 | { | |||
| 311 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 312 | } | 311 | } | |
| 313 | } | 312 | } | |
| 314 | if (component.getComponentType().equals("RunnableThread")) { | 313 | if (component.getComponentType().equals("RunnableThread")) { | |
| 315 | SingleLockState runState=map.get("run"); | 314 | SingleLockState runState=map.get("run"); | |
| 316 | if (locking(runState)) { | 315 | if (locking(runState)) { | |
| 317 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 318 | } | 317 | } | |
| 319 | } | 318 | } | |
| 320 | if (component.getComponentType().equals("Handler")) { | 319 | if (component.getComponentType().equals("Handler")) { | |
| 321 | SingleLockState handleState=map.get("handleMessage"); | 320 | SingleLockState handleState=map.get("handleMessage"); | |
| 322 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 323 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 324 | } | 323 | } | |
| 325 | } | 324 | } | |
| 326 | if (component.getComponentType().equals("BroadcastReceiver")) { | 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 327 | SingleLockState onReceiveState=map.get("onReceive"); | 326 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 328 | if (locking(onReceiveState)) { | 327 | if (locking(onReceiveState)) { | |
| 329 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 330 | } | 329 | } | |
| 331 | } | 330 | } | |
| 332 | } | 331 | } | |
| 333 | } | 332 | } | |
| 334 | } | 333 | } |